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$
正如@Denis已经解释的那样,您可以使用DO
语句遍历系统目录表上的条目.但是,这需要Postgres 9.0或更高版本.您也可以创建一个函数(也适用于8.4).该DO
语句默认使用过程语言plpgsql.
您需要的唯一系统目录是pg_namespace
,保存数据库的模式.循环遍历除已知系统模式之外的所有模式.
确保您已连接到正确的数据库!
要向具有NOT NULL
约束的表添加列,还必须提供用于填充新列的默认值.其他明智的逻辑上不可能.我DEFAULT TRUE
在你的陈述中补充道.根据您的需求调整.
通过引用从系统目录表中检索到的标识符来正确地避免SQL注入.quote_ident()
在这种情况下.还有更多选项(dba.SE上的相关答案).
你需要动态SQL.我的主要技巧是search_path
动态设置,因此可以反复运行相同的语句.SET LOCAL
持续到交易结束的效果.RESET search_path
如果您需要在同一个事务中执行更多操作(不太可能),您可以使用或保存先前状态并重置它:
SHOW search_path INTO _text_var; ... EXECUTE 'SET search_path = ' || _text_var;