sql - 创建检查约束时如何替换变量?
问题描述
我需要为新添加的行添加必填字段。但是,由于表很大,不希望为旧行设置默认值。我需要提供一个自动脚本来执行此操作。我试过这个,但它不起作用:
do $$
declare
max_id int8;
begin
select max(id) into max_id from transactions;
alter table transactions add constraint check_process_is_assigned check (id <= max_id or process_id is not null);
end $$;
解决方案
实用命令如ALTER TABLE
不接受参数。只有基本的 DML 命令SELECT
, INSERT
, UPDATE
,DELETE
可以。看:
您需要动态 SQL,例如:
DO
$do$
BEGIN
EXECUTE format(
'ALTER TABLE transactions
ADD CONSTRAINT check_process_is_assigned CHECK (id <= %s OR process_id IS NOT NULL)'
, (SELECT max(id) FROM transactions)
);
END
$do$;
db<>在这里摆弄
这将创建一个CHECK
基于当前最大值的约束id
。
也许NOT VALID
约束会更好?未针对现有行进行检查:
ALTER TABLE transactions
ADD CONSTRAINT check_process_is_assigned CHECK (process_id IS NOT NULL) NOT VALID;
但是您必须“修复”在这种情况下更新的旧行。(即,process_id
如果它到目前为止为 NULL,则为其分配一个值。)请参阅: