如何只在用户存在的情况下才执行"DROP OWNED BY"?
How to execute "DROP OWNED BY" only if the user exists?
我正在尝试编写一个 bash 脚本来创建一个 Postgres 数据库,以及用户和访问该数据库的用户权限。我正在使用 Postgres 9.6。我有以下...
create_db_command="SELECT 'CREATE DATABASE $DB_NAME' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '$DB_NAME')\gexec"
drop_owned_by_command="DROP OWNED BY $DB_USER;"
drop_role_command="DROP ROLE IF EXISTS $DB_USER;"
create_user_command="create user $DB_USER with encrypted password '$DB_PASS';"
grant_privs_command="grant all privileges on database $DB_NAME to $DB_USER;"
PGPASSWORD=$ROOT_PASSWORD
# This command creates the db if it doesn't already exist
echo "SELECT 'CREATE DATABASE $DB_NAME' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '$DB_NAME')\gexec" | psql -U$PG_USER
psql -U$PG_USER $DB_NAME -c "$drop_owned_by_command"
psql -U$PG_USER -c "$drop_role_command"
psql -U$PG_USER -c "$create_user_command"
psql -U$PG_USER -c "$grant_privs_command"
问题是当脚本第一次 运行 时,命令
DROP OWNED BY $DB_USER;
失败,因为用户尚不存在。有没有一种方法可以编写上述命令,使其仅在用户存在时才 运行 ?类似于 DROP USER IF EXISTS ...
,但 DROP OWNED
没有 IF EXISTS
子句。
您可以使用与 CREATE DATABASE
.
中已有的类似技术
在 shell:
drop_owned_by_command="SELECT 'DROP OWNED BY $DB_USER' FROM pg_roles WHERE rolname = '$DB_USER'\gexec"
echo $drop_owned_by_command | psql -U$PG_USER $DB_NAME
如果角色a实际存在,SELECT
只有returns一行(包含DDL命令)。这又由 psql 命令 \gexec
.
执行
所以我们有 SQL 和 psql 命令的组合,不能使用 psql -c
因为 quoting the manual on --command
:
command
must be either a command string that is completely parsable by the server (i.e., it contains no psql-specific features),
or a single backslash command. Thus you cannot mix SQL and psql
meta-commands within a -c
option.
相反,像演示的那样将回显通过管道传输到 psql - 就像手册和下面我的相关答案中所建议的那样,就像你已经为 CREATE DATABASE
.
所做的那样
相关:
- Simulate CREATE DATABASE IF NOT EXISTS for PostgreSQL?
- Shell script to execute pgsql commands in files
我正在尝试编写一个 bash 脚本来创建一个 Postgres 数据库,以及用户和访问该数据库的用户权限。我正在使用 Postgres 9.6。我有以下...
create_db_command="SELECT 'CREATE DATABASE $DB_NAME' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '$DB_NAME')\gexec"
drop_owned_by_command="DROP OWNED BY $DB_USER;"
drop_role_command="DROP ROLE IF EXISTS $DB_USER;"
create_user_command="create user $DB_USER with encrypted password '$DB_PASS';"
grant_privs_command="grant all privileges on database $DB_NAME to $DB_USER;"
PGPASSWORD=$ROOT_PASSWORD
# This command creates the db if it doesn't already exist
echo "SELECT 'CREATE DATABASE $DB_NAME' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '$DB_NAME')\gexec" | psql -U$PG_USER
psql -U$PG_USER $DB_NAME -c "$drop_owned_by_command"
psql -U$PG_USER -c "$drop_role_command"
psql -U$PG_USER -c "$create_user_command"
psql -U$PG_USER -c "$grant_privs_command"
问题是当脚本第一次 运行 时,命令
DROP OWNED BY $DB_USER;
失败,因为用户尚不存在。有没有一种方法可以编写上述命令,使其仅在用户存在时才 运行 ?类似于 DROP USER IF EXISTS ...
,但 DROP OWNED
没有 IF EXISTS
子句。
您可以使用与 CREATE DATABASE
.
中已有的类似技术
在 shell:
drop_owned_by_command="SELECT 'DROP OWNED BY $DB_USER' FROM pg_roles WHERE rolname = '$DB_USER'\gexec"
echo $drop_owned_by_command | psql -U$PG_USER $DB_NAME
如果角色a实际存在,SELECT
只有returns一行(包含DDL命令)。这又由 psql 命令 \gexec
.
所以我们有 SQL 和 psql 命令的组合,不能使用 psql -c
因为 quoting the manual on --command
:
command
must be either a command string that is completely parsable by the server (i.e., it contains no psql-specific features), or a single backslash command. Thus you cannot mix SQL and psql meta-commands within a-c
option.
相反,像演示的那样将回显通过管道传输到 psql - 就像手册和下面我的相关答案中所建议的那样,就像你已经为 CREATE DATABASE
.
相关:
- Simulate CREATE DATABASE IF NOT EXISTS for PostgreSQL?
- Shell script to execute pgsql commands in files