创建PostgreSQL ROLE(用户)(如果不存在)

问题描述:

如何编写SQL脚本在PostgreSQL 9.1中创建ROLE,但如果已经存在则不引发错误?

How do I write an SQL script to create a ROLE in PostgreSQL 9.1, but without raising an error if it already exists?

当前脚本仅具有:

CREATE ROLE my_user LOGIN PASSWORD 'my_password';

如果用户已经存在,则此操作失败。我想要类似的东西:

This fails if the user already exists. I'd like something like:

IF NOT EXISTS (SELECT * FROM pg_user WHERE username = 'my_user')
BEGIN
    CREATE ROLE my_user LOGIN PASSWORD 'my_password';
END;

...但是不起作用- IF $ c普通的SQL似乎不支持$ c>。

... but that doesn't work - IF doesn't seem to be supported in plain SQL.

我有一个批处理文件,可创建PostgreSQL 9.1数据库,角色和其他一些东西。它调用psql.exe,并传入要运行的SQL脚本的名称。到目前为止,所有这些脚本都是纯SQL,如果可能的话,我想避免使用PL / pgSQL等。

I have a batch file that creates a PostgreSQL 9.1 database, role and a few other things. It calls psql.exe, passing in the name of an SQL script to run. So far all these scripts are plain SQL and I'd like to avoid PL/pgSQL and such, if possible.

简化

DO
$do$
BEGIN
   IF NOT EXISTS (
      SELECT FROM pg_catalog.pg_roles  -- SELECT list can be empty for this
      WHERE  rolname = 'my_user') THEN

      CREATE ROLE my_user LOGIN PASSWORD 'my_password';
   END IF;
END
$do$;

(基于 @a_horse_with_no_name 的答案,并通过 @ Gregory的评论。)

(Building on @a_horse_with_no_name's answer and improved with @Gregory's comment.)

例如,与 创建表 没有如果不存在code>子句,用于 创建角色 (至少第12页)。而且,您不能在普通SQL中执行动态DDL语句。

Unlike, for instance, with CREATE TABLE there is no IF NOT EXISTS clause for CREATE ROLE (up to at least pg 12). And you cannot execute dynamic DDL statements in plain SQL.

您的避免PL / pgSQL请求是不可能的,除非使用另一个PL。 DO 语句使用plpgsql作为默认过程语言。语法允许省略显式声明:

Your request to "avoid PL/pgSQL" is impossible except by using another PL. The DO statement uses plpgsql as default procedural language. The syntax allows to omit the explicit declaration:


DO [语言 lang_name ]代码

...

lang_name

编写代码的过程语言的名称。如果省略
,则默认值为 plpgsql