0

我一直在尝试创建一个脚本来检测一个角色已经存在,如果它存在,它应该撤销所有特权。这样做很好:

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$$;

但是现在我希望每个环境都是动态的,因为我将在每个环境中使用不同的角色名称。所以我尝试使用 \set 机制,但是在使用 pl/sql 时这似乎不起作用,所以如果我会做类似以下的事情 Postgresql 抱怨语法错误:

/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$$;

虽然如果我不在 pl/sql 中这样做,撤销语句就可以正常工作。所以我的问题是如何通过将参数传递给它来使我的脚本动态化,以便它们被替换?

4

1 回答 1

4

您必须使用EXECUTE动态 SQL。此外,DO语句不能带参数。创建一个 plpgsql 函数:

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;

称呼:

SELECT f_revoke_all_from_role('superman');
  • IF使用 .block 更简单EXISTS

  • quote_ident()用来避免 SQLi。

  • 表名可以是函数的第二个参数...

于 2012-07-10T19:05:35.243 回答