2015-02-11 70 views
0

我的規則更新視圖「fva_gpi_sbcpcba_voapcba」沒有正確更新「general_product_info」和「fva_3800」表中的「product_serial_number」列。視圖更新規則 - PostgreSQL

它僅更新寫入更新規則中的第一個表中的「product_serial_number」,而不是兩者。也就是說,在這種情況下,它將更新fva_3800表的product_serial_number,但不更新general_product_info表。如果我把UPDATE放在general_product_info表中,反之亦然。

更新規則:(去除過長的和不重要的代碼,取而代之的...)

CREATE RULE update_fva_fullview 
AS ON UPDATE TO fva_gpi_sbcpcba_voapcba 
DO INSTEAD 
(UPDATE voa_pcba 
SET (voa_pcba_serial_number, ..., ch4_voa_cqr_link) 
= (NEW.voa_pcba_serial_number, ..., NEW.ch4_voa_cqr_link) 
WHERE voa_pcba_serial_number = OLD.voa_pcba_serial_number; 
UPDATE sbc_pcba 
SET (sbc_pcba_serial_number, sbc_fw_revision, sbc_mac_address, sbc_test_result_link) 
= (NEW.sbc_pcba_serial_number, NEW.sbc_fw_revision, NEW.sbc_mac_address, NEW.sbc_test_result_link) 
WHERE sbc_pcba_serial_number = OLD.sbc_pcba_serial_number; 
UPDATE fva_3800 
SET (product_serial_number, status_pcba_serial_number, sbc_pcba_serial_number, voa_pcba_serial_number) 
= (NEW.product_serial_number, NEW.status_pcba_serial_number, NEW.sbc_pcba_serial_number, NEW.voa_pcba_serial_number) 
WHERE product_serial_number = OLD.product_serial_number; 
UPDATE general_product_info 
SET (product_serial_number, part_number, innovator_product_bom, calibration_certificate, manual, 
application_sw_name, application_sw_rev, test_report_link, production_exceptions, notes) 
= (NEW.product_serial_number, NEW.part_number, NEW.innovator_product_bom, NEW.calibration_certificate, NEW.manual, 
NEW.application_sw_name, NEW.application_sw_rev, NEW.test_report_link, NEW.production_exceptions, NEW.notes) 
WHERE product_serial_number = OLD.product_serial_number;); 

查看:(全...對不起,這是漫長的,但我寧願不引起混亂)

CREATE OR REPLACE VIEW fva_gpi_sbcpcba_voapcba AS 
SELECT product_serial_numbers.product_serial_number, general_product_info.part_number, general_product_info.innovator_product_bom, 
general_product_info.calibration_certificate, general_product_info.manual, general_product_info.application_sw_name, 
general_product_info.application_sw_rev, general_product_info.test_report_link, fva_3800.status_pcba_serial_number, 
sbc_pcba.sbc_pcba_serial_number, sbc_pcba.sbc_fw_revision, sbc_pcba.sbc_mac_address, sbc_pcba.sbc_test_result_link, 
voa_pcba.voa_pcba_serial_number, voa_pcba.voa_fw_revision, voa_pcba.voa_test_result_link, voa_pcba.ch1_tap_part_number, 
voa_pcba.ch1_tap_serial_number, voa_pcba.ch1_tap_cqr_link, voa_pcba.ch1_voa_part_number, voa_pcba.ch1_voa_serial_number, 
voa_pcba.ch1_voa_cqr_link, voa_pcba.ch2_tap_part_number, voa_pcba.ch2_tap_serial_number, voa_pcba.ch2_tap_cqr_link, 
voa_pcba.ch2_voa_part_number, voa_pcba.ch2_voa_serial_number, voa_pcba.ch2_voa_cqr_link, voa_pcba.ch3_tap_part_number, 
voa_pcba.ch3_tap_serial_number, voa_pcba.ch3_tap_cqr_link, voa_pcba.ch3_voa_part_number, voa_pcba.ch3_voa_serial_number, 
voa_pcba.ch3_voa_cqr_link, voa_pcba.ch4_tap_part_number, voa_pcba.ch4_tap_serial_number, voa_pcba.ch4_tap_cqr_link, 
voa_pcba.ch4_voa_part_number, voa_pcba.ch4_voa_serial_number, voa_pcba.ch4_voa_cqr_link, general_product_info.production_exceptions, 
general_product_info.notes, general_product_info.gpi_id 
FROM product_serial_numbers 
INNER JOIN general_product_info ON product_serial_numbers.product_serial_number = general_product_info.product_serial_number 
INNER JOIN fva_3800 ON product_serial_numbers.product_serial_number = fva_3800.product_serial_number 
INNER JOIN sbc_pcba ON fva_3800.sbc_pcba_serial_number = sbc_pcba.sbc_pcba_serial_number 
INNER JOIN voa_pcba ON fva_3800.voa_pcba_serial_number = voa_pcba.voa_pcba_serial_number; 

PRODUCT_SERIAL_NUMBER是在product_serial_numbers表一個p鍵,並在general_product_info和fva_3800表的唯一FKEY。

編輯:

fva_3800_product_serial_number_fkey FOREIGN KEY (product_serial_number) REFERENCES product_serial_numbers(product_serial_number) ON UPDATE CASCADE ON DELETE SET NULL 

爲fkeys約束的所有都是這樣的。他們都有CASCADE和SET NULL。

這裏是fva_3800表的定義:

CREATE TABLE FVA_3800 (
    id serial CONSTRAINT fva_3800_id_pkey PRIMARY KEY, 
    product_serial_number varchar(32) UNIQUE REFERENCES Product_Serial_Numbers(product_serial_number) ON UPDATE CASCADE ON DELETE SET NULL, 
    status_PCBA_serial_number varchar(32), 
    SBC_PCBA_serial_number varchar(32) REFERENCES SBC_PCBA(SBC_PCBA_serial_number) ON UPDATE CASCADE ON DELETE SET NULL, 
    VOA_PCBA_serial_number varchar(32) REFERENCES VOA_PCBA(VOA_PCBA_serial_number) ON UPDATE CASCADE ON DELETE SET NULL 
); 
+0

你能後的(略)表定義?最可能的原因是表'general_product_info'和'fva_3800'的'FOREIGN KEY'子句中的引用操作('ON UPDATE CASCADE?')到表'product_serial_numbers'。 – Patrick 2015-02-11 01:41:09

+0

我可以告訴你,所有的fkey約束都有ON UPDATE CASCADE和ON DELETE SET TO NULL 我將在主帖 – 2015-02-11 02:11:21

+0

上更新這些細節雖然我只是嘗試將兩個fkey約束更改爲沒有級聯或設置的簡單fkey在general_product_info和fva_3800表上都爲null,但它仍不能解決問題。 – 2015-02-11 02:25:43

回答

0

而不是使用規則,我用函數和觸發器。

規則只是沒有在這種情況下正常工作的更新,也沒有刪除

CREATE FUNCTION update_fva_full() RETURNS TRIGGER AS $_$ 
BEGIN 
UPDATE voa_pcba 
SET (voa_pcba_serial_number, voa_fw_revision, voa_test_result_link, ch1_tap_part_number, ch1_tap_serial_number, ch1_tap_cqr_link, 
ch1_voa_part_number, ch1_voa_serial_number, ch1_voa_cqr_link, ch2_tap_part_number, ch2_tap_serial_number, ch2_tap_cqr_link, 
ch2_voa_part_number, ch2_voa_serial_number, ch2_voa_cqr_link, ch3_tap_part_number, ch3_tap_serial_number, ch3_tap_cqr_link, 
ch3_voa_part_number, ch3_voa_serial_number, ch3_voa_cqr_link, ch4_tap_part_number, ch4_tap_serial_number, ch4_tap_cqr_link, 
ch4_voa_part_number, ch4_voa_serial_number, ch4_voa_cqr_link) 
= (NEW.voa_pcba_serial_number, NEW.voa_fw_revision, NEW.voa_test_result_link, NEW.ch1_tap_part_number, NEW.ch1_tap_serial_number, NEW.ch1_tap_cqr_link, 
NEW.ch1_voa_part_number, NEW.ch1_voa_serial_number, NEW.ch1_voa_cqr_link, NEW.ch2_tap_part_number, NEW.ch2_tap_serial_number, NEW.ch2_tap_cqr_link, 
NEW.ch2_voa_part_number, NEW.ch2_voa_serial_number, NEW.ch2_voa_cqr_link, NEW.ch3_tap_part_number, NEW.ch3_tap_serial_number, NEW.ch3_tap_cqr_link, 
NEW.ch3_voa_part_number, NEW.ch3_voa_serial_number, NEW.ch3_voa_cqr_link, NEW.ch4_tap_part_number, NEW.ch4_tap_serial_number, NEW.ch4_tap_cqr_link, 
NEW.ch4_voa_part_number, NEW.ch4_voa_serial_number, NEW.ch4_voa_cqr_link) 
WHERE voa_pcba_serial_number = OLD.voa_pcba_serial_number; 
UPDATE sbc_pcba 
SET (sbc_pcba_serial_number, sbc_fw_revision, sbc_mac_address, sbc_test_result_link) 
= (NEW.sbc_pcba_serial_number, NEW.sbc_fw_revision, NEW.sbc_mac_address, NEW.sbc_test_result_link) 
WHERE sbc_pcba_serial_number = OLD.sbc_pcba_serial_number; 
UPDATE fva_3800 
SET (product_serial_number, status_pcba_serial_number, sbc_pcba_serial_number, voa_pcba_serial_number) 
= (NEW.product_serial_number, NEW.status_pcba_serial_number, NEW.sbc_pcba_serial_number, NEW.voa_pcba_serial_number) 
WHERE product_serial_number = OLD.product_serial_number; 
UPDATE general_product_info 
SET (product_serial_number, part_number, innovator_product_bom, calibration_certificate, manual, 
application_sw_name, application_sw_rev, test_report_link, production_exceptions, notes) 
= (NEW.product_serial_number, NEW.part_number, NEW.innovator_product_bom, NEW.calibration_certificate, NEW.manual, 
NEW.application_sw_name, NEW.application_sw_rev, NEW.test_report_link, NEW.production_exceptions, NEW.notes) 
WHERE product_serial_number = OLD.product_serial_number; 
RETURN OLD; 
END $_$ LANGUAGE 'plpgsql'; 

CREATE TRIGGER update_from_fva_view 
INSTEAD OF UPDATE ON fva_gpi_sbcpcba_voapcba 
FOR EACH ROW EXECUTE PROCEDURE update_fva_full();