2016-02-11 77 views
0

在PostgreSQL 9.5,我有一個表:一個批量移動

表A有兩個屬性:

  1. recid - 主爲表(串行)
  2. 描述鍵 - 表(文本)的唯一密鑰

表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的新記錄。

這是如何完成的?可以使用可寫的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」上的外鍵約束「nursebilling_cpt_fk」詳細信息:鍵(recid)=(459)仍然從表「 nursebilling」。

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

不清楚。也許你的意思是DEFERRED約束? – wildplasser

+0

@wildplasser主鍵的約束可以被拒絕嗎? –

+0

請給出完整的DDL。文字不明確。恕我直言。 – wildplasser

回答

0

那麼,經過進一步調查,問題的癥結而泄露其內容Erwin Brandstetter

If you need any FOREIGN KEY constraints to reference the column(s), DEFERRABLE is not an option because (per documentation):

The referenced columns must be the columns of a non-deferrable unique or primary key constraint in the referenced table.

因此,CTE的都出來了,我留下了一個PLPGSQL腳本,以某種方式將有顯式查找子表,移動子記錄,然後刪除舊的父記錄。