问题
I have been trying to create a script that detects that a role already excists and if it does it should revoke all privileges. This works fine doing it like this:
DO $$DECLARE count int;
BEGIN
SELECT count(*) INTO count FROM pg_roles WHERE rolname = 'superman';
IF count > 0 THEN
REVOKE ALL PRIVILEGES ON TABLE FROM superman;
END IF;
END$$;
But now I want this to be dynamic per environment since I will be using different role names per environment. So I tried to use the \set mechanism but that doesn't seem to work when using pl/sql so if I would do something like the following Postgresql is complaining with syntax errors:
/set environment _int
DO $$DECLARE count int;
BEGIN
SELECT count(*) INTO count FROM pg_roles WHERE rolname = 'superman';
IF count > 0 THEN
REVOKE ALL PRIVILEGES ON TABLE FROM superman:environment;
END IF;
END$$;
Although if I would not do it in pl/sql the revoke statment works just fine. So my question is how can I make my script dynamic by passing parameters to it so they will be replaced?
回答1:
You have to use EXECUTE for dynamic SQL. Also, a DO
statement cannot take parameters. Create a plpgsql function:
CREATE OR REPLACE FUNCTION f_revoke_all_from_role(_role text)
RETURNS void AS
$BODY$
BEGIN
IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = _role) THEN
EXECUTE 'REVOKE ALL PRIVILEGES ON TABLE x FROM ' || quote_ident(_role);
END IF;
END;
$BODY$ LANGUAGE plpgsql;
Call:
SELECT f_revoke_all_from_role('superman');
IF
block is simpler withEXISTS
.I use quote_ident() to avoid SQLi.
The table name could be the second parameter of the function ...
来源:https://stackoverflow.com/questions/11419793/detect-role-in-postgresql-dynamically