我有一个如下所示的 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/