小编典典

从匿名块中的变量创建带有密码的用户

sql

我想创建一个将包含变量的脚本,_user并且 当尚不存在这种登录名
时才_pass在Postgres数据库中创建用户。我以为这会起作用,但是我不能说出问题所在: __

DO
$DO$
DECLARE
  _user TEXT := 'myuser';
  _pass TEXT := 'user!pass';
BEGIN
   IF NOT EXISTS ( SELECT 1 FROM   pg_catalog.pg_roles WHERE  rolname = _user) THEN
        RAISE NOTICE 'Creating user % ...',_user;
        CREATE USER _user WITH
            LOGIN
            NOSUPERUSER
            CREATEDB
            CREATEROLE
            NOREPLICATION
            PASSWORD _pass;

        RAISE NOTICE 'Created user %',_user;
   ELSE
        RAISE NOTICE 'User % already exists, not creating it',_user;
   END IF;
END
$DO$

如何强制用变量内容替换变量?

而且$DO$和之间有什么区别$$


阅读 161

收藏
2021-04-14

共1个答案

小编典典

要参数化标识符或语法元素,通常需要将动态SQL与EXECUTE-最好结合使用,format()以易于使用。

但实用的命令(包括所有SQL DDL语句)不允许值或参数替换的传递 在所有 。您需要先连接完整的语句,然后再执行它。

您的代码将像这样工作:

DO
$do$
DECLARE
  _user text := 'myuser';
  _pass text := 'user!pass';
BEGIN
   IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = _user) THEN
      EXECUTE format(
        'CREATE USER %I WITH
            LOGIN
            NOSUPERUSER
            CREATEDB
            CREATEROLE
            NOREPLICATION
            PASSWORD %L'
         , _user
         , _pass
         );
      RAISE NOTICE 'Created user "%"', _user;
   ELSE
      RAISE NOTICE 'User "%" already exists, not creating it', _user;
   END IF;
END
$do$

但是,尽管无论如何都对_user_pass进行了硬编码,但您可以像下面的示例所示进行简化:

而且$DO$和之间有什么区别$$

看:

2021-04-14