在PSQL中执行一系列命令

Sij*_*tha 5 postgresql psql postgresql-9.5

我正在寻找在 PSQL 中执行多个命令的解决方案。

假设我有一个数据库名称为2 的文件。

1. slave1
2. slave2
Run Code Online (Sandbox Code Playgroud)

我已经有一个名为“ master_db”的主模板。

如果我手动完成,我将执行以下操作:

CREATE DATABASE slave1 TEMPLATE master_db;
CREATE DATABASE slave2 TEMPLATE master_db;
Run Code Online (Sandbox Code Playgroud)

如果只有 2 个,那会很容易,但在我的情况下有 30 个以上,因此我想知道我们是否可以创建一个脚本。我确实尝试过搜索,但找不到解决方案。

如果这很重要,数据库在同一个集群中。

dez*_*zso 10

如果您使用的是psql9.6+,有一个非常方便的命令叫做\gexec

将当前查询输入缓冲区发送到服务器,然后将查询输出(如果有)的每一行的每一列视为要执行的 SQL 语句。[...] 生成的查询按返回行的顺序执行,如果有多于一列,则在每行内从左到右执行。NULL 字段被忽略。生成的查询按字面发送到服务器进行处理,因此它们不能是 psql 元命令,也不能包含 psql 变量引用。

因此,您的脚本可能如下所示:

SELECT format('create database slave%s template master_db', l_num) 
  FROM generate_series(1, 30) t(l_num);

\gexec
Run Code Online (Sandbox Code Playgroud)

请注意psql,即使服务器版本较低,您也可以使用较新的版本。可能有一些不兼容的罕见情况(使用\d*命令时,因为某些系统视图可能会在服务器版本之间发生变化),但我还没有看到这种情况。

如果您仍然停留在较早的客户端版本上,您可以使用SELECT并将输出手动复制到脚本文件中。

如果您的数据库名称在一个文件中,您有多种选择。要么使用编辑器处理该文件(类似于sed -i -e 's/^/CREATE\ DATABASE\ /' -e 's/$/\ TEMPLATE\ master_db'任何sed存在的操作系统),然后运行生成的脚本。

或者,您也可以执行以下操作:

CREATE TEMPORARY TABLE db_names (db text);

\copy db_names FROM 'path/to/your/file'

SELECT format('create database slave%s template master_db', db) 
  FROM db_names;

\gexec
Run Code Online (Sandbox Code Playgroud)

重要提示:仅当您绝对信任您正在使用的来源时才使用 \gexec。上述方法容易发生SQL 注入(有趣的是,当同一行上的命令之一是 时,这并不容易CREATE DATABASE,但小心总比事后后悔好)。