Detect role in Postgresql dynamically

拜拜、爱过 提交于 2019-12-12 00:52:44

问题


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 with EXISTS.

  • 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!