我想创建一个将包含变量的脚本,_user并且 仅 当尚不存在这种登录名 时才_pass在Postgres数据库中创建用户。我以为这会起作用,但是我不能说出问题所在: __
_user
_pass
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$和之间有什么区别$$?
$DO$
$$
要参数化标识符或语法元素,通常需要将动态SQL与EXECUTE-最好结合使用,format()以易于使用。
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进行了硬编码,但您可以像下面的示例所示进行简化:
看: