【问题标题】:Update Rule on View - PostgreSQL更新视图规则 - PostgreSQL
【发布时间】:2015-02-11 00:01:48
【问题描述】:

我更新视图“fva_gpi_sbcpcba_voapcba”的规则没有正确更新“general_product_info”和“fva_3800”表中的“product_serial_number”列。

它只更新写入更新规则的第一个表中的“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 表中的 pkey,在 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
);

【问题讨论】:

  • 你能发布(缩写的)表定义吗?最可能的原因是表 general_product_infofva_3800FOREIGN KEY 子句中对表 product_serial_numbers 的引用操作 (ON UPDATE CASCADE?)。
  • 我可以告诉你,fkey 约束都有 ON UPDATE CASCADE 和 ON DELETE SET TO NULL 我将在主帖上更新这些细节
  • 虽然我只是尝试将两个 fkey 约束更改为一个没有级联的简单 fkey,也没有在 general_product_info 和 fva_3800 表上设置 null,但它仍然没有解决问题。

标签: postgresql view rule


【解决方案1】:

我没有使用规则,而是使用了函数和触发器。

在这种情况下,规则无法正常用于 UPDATE 或 DELETE

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();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-17
    • 2023-02-07
    • 1970-01-01
    • 1970-01-01
    • 2012-10-20
    • 2022-11-30
    • 1970-01-01
    相关资源
    最近更新 更多