sql - 向 PostgreSQL 数据库的所有模式中的表添加一列

标签 sql postgresql plpgsql ddl postgresql-8.4

我有一个如下所示的 Postgres 8.4 模式:

My_Database
 |-> Schemas
       |-> AccountA
       |-> AccountB
       |-> AccountC
       |-> AccountD
       |-> AccountE
      ...
       |-> AccountZ

所有模式都有一个名为 product 的表,我想立即向它们添加一个 bool 列。可以这样做吗?

到目前为止,我发现的唯一方法是按帐户运行以下 SQL 帐户。

ALTER TABLE product ADD COLUMN show_price boolean NOT NULL DEFAULT TRUE;

最佳答案

DO
$do$
DECLARE
  _schema text;
  _sp
BEGIN
   FOR _schema IN
      SELECT quote_ident(nspname)  -- prevent SQL injection
      FROM   pg_namespace n
      WHERE  nspname !~~ 'pg_%'
      AND    nspname <>  'information_schema'
   LOOP
      EXECUTE 'SET LOCAL search_path = ' || _schema;
      ALTER TABLE product ADD COLUMN show_price boolean NOT NULL DEFAULT TRUE;
   END LOOP;
END
$do$

您可以使用 DO statement 遍历系统目录表中的条目.需要 Postgres 9.0 或更高版本
您也可以create a function . DO 语句使用 procedural language plpgsql默认情况下。

您唯一需要的系统目录是 pg_namespace,它包含数据库的模式。遍历除已知系统模式之外的所有模式。

确保您已连接到正确的数据库!

要向具有 NOT NULL 约束的表添加列,您还必须提供默认值来填充新列。否则逻辑上不可能。我添加了DEFAULT TRUE,根据您的需要进行调整。

通过正确引用从系统目录表中检索到的标识符来避免 SQL 注入(inject)。 quote_ident() 在这种情况下。 [还有更多选择。见:

您需要动态 SQL。主要的“技巧”是设置 search_path动态地,所以同一个语句可以一遍又一遍地运行。 SET LOCAL的效果持续到交易结束。您可以使用 RESET search_path 或保存之前的状态并在您需要在同一事务中使用它执行更多操作时重置它(不太可能):

SHOW search_path INTO _text_var;
...
EXECUTE 'SET search_path = ' || _text_var;

关于sql - 向 PostgreSQL 数据库的所有模式中的表添加一列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20273246/

相关文章:

mysql - 如何在不丢失数据的情况下自动递增此表?

c# - 从数据库中检查字符串值

postgresql - 从函数调用中分配带有 UUID 字段的复杂类型

sql - 在 SQL 中插入不应该包含 null 的记录

database - 使用 group by 子句计算行数

postgresql - 我无法从主机访问已安装的 docker-postgres 卷

postgresql - 如何使用 knex 和 postgresql 有条件地更新多行?

postgresql - 将参数传递给 Postgres 中的存储函数

sql - PL/pgSQL SELECT 到一个数组

sql - 计算一个表中两个日期之间差异的TSQL问题