如果此类登录尚不存在,我想创建一个包含_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$
和$$
之间有什么区别?
答案 0 :(得分: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$
和$$
之间有什么区别?
请参阅:
答案 1 :(得分:0)
使用自定义选项的另一种方法(引用Erwin的较早答案):
又名bash:
set -x
PGPASSWORD="${postgres_db_useradmin_pw:-}" psql -q -t -X \
-w -U "${postgres_db_useradmin:-}" \
-h $postgres_db_host -p $postgres_db_port \
-v ON_ERROR_STOP=1 \
-v postgres_db_user="${postgres_db_user:-}" \
-v postgres_db_user_pw="${postgres_db_user_pw:-}" \
-v postgres_db_name="${postgres_db_name:-}" \
-f "$sql_script" "${postgres_db_name:-}" > "$tmp_log_file" 2>&1
和pgsql
SET myvars.postgres_db_user TO :'postgres_db_user';
SET myvars.postgres_db_user_pw TO :'postgres_db_user_pw';
DO
$do$
BEGIN
EXECUTE format(
'CREATE ROLE %I WITH PASSWORD %L LOGIN'
, current_setting('myvars.postgres_db_user', true)::text
, current_setting('myvars.postgres_db_user_pw', true)::text
);
RAISE NOTICE 'Created user "%"',
current_setting('myvars.postgres_db_user', true)::text;
EXCEPTION WHEN OTHERS THEN
RAISE NOTICE 'User "%" already exists, not creating it',
current_setting('myvars.postgres_db_user', true)::text;
EXECUTE format(
'ALTER ROLE %I WITH PASSWORD %L LOGIN'
, current_setting('myvars.postgres_db_user', true)::text
, current_setting('myvars.postgres_db_user_pw', true)::text
);
END
$do$;
值得注意的是,通过将bash vars插值和sql结合使用,通常可以更容易地获得相同的结果,如下所示: https://github.com/YordanGeorgiev/qto/blob/master/src/bash/qto/funcs/provision-db-admin.func.sh