我需要从两个表中复制记录并再次将它们重新插入到这些表中,只有一个字段不同(父表为PK,子表为PK,FK)。 PK可以从SEQUENCE中获取,我面临的问题是如何级联更新子表中的FK。
我有下表 My_List ,其中 Sup_ID 是主键
My_List
+--------+----------+-----------+ | Sup_ID | Sup_Name | Sup_Code | +--------+----------+-----------+ | 1 | AA | 23 | | 2 | BB | 87 | | 3 | CC | 90 | +--------+----------+-----------+
下表 My_List_details ,其中 Buy_ID 是主键(取自SEQUENCE,假定已创建), Sup_ID 是外键点在 My_List.Sup_ID
My_List_details
+--------+--------+------------+------------+------------+ | Buy_ID | Sup_ID | Sup_Detail | Max_Amount | Min_Amount | +--------+--------+------------+------------+------------+ | 33 | 1 | AAA | 1 | 10 | | 34 | 2 | BBB | 11 | 20 | | 35 | 3 | CCC | 21 | 30 | | 36 | 2 | BBB | 11 | 20 | +--------+--------+------------+------------+------------+
-------------------------------------------- -------
目标
写PL / SQL函数执行以下操作:
-------------------------------------------- ----------------------------------
预期结果
My_List
+--------+----------+----------+ | Sup_ID | Sup_Name | Sup_Code | +--------+----------+----------+ | 1 | AA | 23 | | 2 | BB | 87 | | 3 | CC | 90 | | 4 | AA | 23 | | 5 | BB | 87 | | 6 | CC | 90 | +--------+----------+----------+
My_List_details
+--------+--------+------------+------------+------------+ | Buy_ID | Sup_ID | Sub_Detail | Max_Amount | Min_Amount | +--------+--------+------------+------------+------------+ | 33 | 1 | AAA | 1 | 10 | | 34 | 2 | BBB | 11 | 20 | | 35 | 3 | CCC | 21 | 30 | | 36 | 2 | BBB | 11 | 20 | | 37 | 1 | AAA | 1 | 10 | | 38 | 2 | BBB | 11 | 20 | | 39 | 3 | CCC | 21 | 30 | | 40 | 2 | BBB | 11 | 20 | +--------+--------+------------+------------+------------+
我开始的是以下内容:
BEGIN
FOR d IN (
SELECT Sup_Name, Sup_Code
FROM My_List
)
LOOP
INSERT INTO MY_List SELECT Sup_ID.NEXTVAL, Sup_Name, Sup_Code
END LOOP;
END;
/
但是,我不确定以下内容:
答案 0 :(得分:0)
我认为好的解决方案是通过附加列扩展所有主键,当克隆记录发生时,该列将通过触发器递增。 我们称这个附加列为SEC_ID。 SEC_ID应该在一个主键的上下文中递增和使用。 您不必在表中创建与SEC_ID列一样多的序列。您可以在触发器中查询最后一个sec_id作为您的ID,然后将其递增以插入具有原始ID的新有效主键。
优点:
简单机制
简单扩展新表
答案 1 :(得分:0)
我发现以下内容解决了我的问题(假设sup_seq和buy_seq是两个创建的SEQUENCES):
DECLARE
CURSOR cOld IS
SELECT *
FROM my_list;
new_id NUMBER;
BEGIN
FOR rOld IN cOld LOOP
new_id := sup_seq.NEXTVAL; -- Get the ID to use for the new row
INSERT INTO my_list
(sup_id,sup_name,sup_code)
VALUES (new_id,rOld.sup_name,rOld.sup_code);
INSERT INTO my_list_details
(buy_id,sup_id,sup_detail,max_amount,min_amount)
SELECT buy_seq.NEXTVAL,new_id,sup_detail,max_amount,min_amount
FROM my_list_details
WHERE sup_id = rOld.sup_id;
END LOOP;
END;
如果问题可以通过其他方式解决,可能不建议使用光标,对我来说,我发现它更容易阅读和维护。