我有几个布尔列的PostgreSQL表,目前只包含true或null。我想对所有人做以下事情:
not null
约束即:
-- for each column specified:
update my_table set my_column = 'f' where my_column is null;
alter table my_table alter column my_column set default 'f';
alter table my_table alter column my_column set not null;
是否有psql(或标准SQL)的功能将迭代指定的列列表并对每个列应用一系列操作?
答案 0 :(得分:15)
你不能遍历所有列,但为了安全起见,你可能不想这样做但是指定哪些要改变自己。另一种方法是执行脚本查询列名,然后更改它们。
要更改它们,请使用ALTER TABLE
。请参阅PgSQL文档:
http://www.postgresql.org/docs/8.4/static/sql-altertable.html
ALTER TABLE xy ALTER COLUMN a SET DEFAULT FALSE, ALTER COLUMN b SET NOT NULL
等
答案 1 :(得分:5)
这样做,因为VARIADIC需要8.4或更高版本。
CREATE OR REPLACE FUNCTION setdefaults(
IN _tname TEXT, -- tablename to alter
VARIADIC _cname TEXT[] -- all columnnames to alter
)
RETURNS boolean
LANGUAGE plpgsql
AS
$$
DECLARE
row record;
BEGIN
FOR row IN SELECT unnest(_cname) AS colname LOOP
EXECUTE 'ALTER TABLE ' || quote_ident(_tname) || ' ALTER COLUMN ' || quote_ident(row.colname) || ' SET DEFAULT false;';
EXECUTE 'UPDATE ' || quote_ident(_tname) || ' SET ' || quote_ident(row.colname) || ' = DEFAULT WHERE ' || quote_ident(row.colname) || ' IS NULL;';
EXECUTE 'ALTER TABLE ' || quote_ident(_tname) || ' ALTER COLUMN ' || quote_ident(row.colname) || ' SET NOT NULL;';
END LOOP;
RETURN TRUE;
END;
$$;
SELECT setdefaults('foo', 'x','y','z'); -- alter table "foo"