在PostgreSQL 9.5中,我有一个表:A
表A有两个属性:
表A的主键被其他表用作外键,其定义为:
CONSTRAINT fk FOREIGN KEY (A_recid)
REFERENCES A (recid) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE RESTRICT
我需要将表A中记录1中的描述更改为记录2中已存在的描述,并删除记录1以保持表的唯一描述。
表A中的记录1将在其他表中具有子记录,这些子记录需要根据外键约束的级联更新移动到记录2的新recid。
这是怎么做到的?是否可以使用可写的CTE?
(如有必要,我不反对改变表格设计)。
非常感谢任何建议。
编辑#1父表的完整表声明是:
CREATE TABLE cpt
(
recid serial NOT NULL,
code text,
cdesc text NOT NULL,
modified timestamp without time zone DEFAULT now(),
procedure_type text,
CONSTRAINT pk_cpt_recid PRIMARY KEY (recid),
CONSTRAINT cpt_noduplicate UNIQUE (cdesc)
)
WITH (
OIDS=FALSE
);
ALTER TABLE cpt
OWNER TO postgres;
子表的示例(许多表中的一个):
CREATE TABLE cpt_invoice
(
recid serial NOT NULL,
cpt_recid integer NOT NULL,
ninsurance numeric(10,2),
ncash numeric(10,2),
mustschedule boolean,
doneinoffice boolean,
common boolean,
"timestamp" timestamp without time zone DEFAULT now(),
modified timestamp without time zone DEFAULT now(),
CONSTRAINT pk_cpt_invoice_recid PRIMARY KEY (recid),
CONSTRAINT cs_cpt_invoice FOREIGN KEY (cpt_recid)
REFERENCES cpt (recid) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT cs_unique_cpt_invoice UNIQUE (cpt_recid)
)
WITH (
OIDS=FALSE
);
ALTER TABLE cpt_invoice
OWNER TO postgres;
编辑#2:这是我所希望的。但这不适用于错误:
错误:更新或删除表格" cpt"违反外键约束" nursebilling_cpt_fk"在桌子上"护士"详细信息:Key(recid)=(459)仍然从表格#34; carebilling"中引用。
with plana as ( -- get snapshot of original record
select * from cpt where recid = 459
)
, planb as ( -- change the primary key on snapshot -- I am hoping this will be cascaded
update cpt
set recid = 2
from plana
where cpt.recid = plana.recid
)
, planc as ( -- delete the one-to-one record in cpt_invoice
delete from cpt_invoice
using planA
where cpt_invoice.cpt_recid = planA.recid
)
, pland as( -- delete the now unused record from cpt
delete from cpt
using plana
where plana.cdesc = cpt.cdesc
)
select * from cpt
答案 0 :(得分:0)
嗯,经过进一步调查后,Erwin Brandstetter
披露了问题的关键如果您需要任何FOREIGN KEY约束来引用列, DEFERRABLE不是一个选项,因为(根据文档):
引用的列必须是不可延迟的唯一列 或引用表中的主键约束。
因此,CTE已经出局了,我留下了一个plpgsql脚本,它在某种程度上必须显式查找子表,移动子记录,然后删除旧的父记录。