鉴于数据结构:
我有下表 My_List ,其中 Sup_ID 是主键
My_List
+--------+----------+-----------+ | Sup_ID | Sup_Name | Sup_Code | +--------+----------+-----------+ | 1 | AA | 23 | | 2 | BB | 87 | | 3 | CC | 90 | +--------+----------+-----------+
下表 _MyList_details ,其中 Buy_ID 是主键,而 Sup_ID 是 My_List.Sup_ID 的外键点
My_List_details
+--------+--------+------------+------------+------------+ | Buy_ID | Sup_ID | Sup_Detail | Max_Amount | Min_Amount | +--------+--------+------------+------------+------------+ | 23 | 1 | AAA | 1 | 10 | | 33 | 2 | BBB | 11 | 20 | | 43 | 3 | CCC | 21 | 30 | +--------+--------+------------+------------+------------+
最后,我有 My_Sequence 表格如下:
My_Sequence
+-----+------+ | Seq | Name | +-----+------+ | 4 | x | | 5 | y | | 6 | z | +-----+------+
-------------------------------------------- -------
目标
将PL / SQL脚本写入:
-------------------------------------------- ----------------------------------
预期结果
My_List
+--------+----------+----------+ | Sup_ID | Sub_Name | Sub_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 | +--------+--------+------------+------------+------------+ | 23 | 1 | AAA | 1 | 10 | | 33 | 2 | BBB | 11 | 20 | | 43 | 3 | CCC | 21 | 30 | | 53 | 4 | AAA | 1 | 10 | | 63 | 5 | BBB | 11 | 20 | | 73 | 6 | CCC | 21 | 30 | +--------+--------+------------+------------+------------+
我开始的是以下内容:
DECLARE
NEW_Sup_ID Sup_ID%type := Seq;
c_Sup_Name Sup_Name%type;
c_Sup_Code Sup_Code%type;
c_Buy_ID Buy_ID%type;
c_Sup_Detail Sup_Detail%type;
c_Max_Amount Max_Amount%type
c_My_Min_Amount Min_Amount%type
CURSOR c_My_List
IS
SELECT * FROM My_List;
CURSOR c_My_List_details
IS
SELECT * FROM My_List_details
BEGIN
FETCH c_My_List INTO NEW_Sup_ID, c_Sup_Name, c_Sup_Code;
INSERT INTO My_List;
FETCH c_My_List_details INTO c_Buy_ID, NEW_Sup_ID, c_Sup_Detail, c_Max_Amount, c_Min_Amount
INSERT INTO My_List_details
END;
/
除了语法错误之外,我没有看到我的脚本逐行复制并相应地将它们插入到两个表中。此外, My_Sequence 记录的数量大于 My_List 记录的数量。所以我需要的是,如果 My_List 记录是50,我需要脚本从 My_Sequence 复制前50个 Seq 。
-------------------------------------------- -------------------------------------
问题
如何实现这一结果?我搜索并发现了Tom Kyte级联更新,但我不确定是否需要使用此软件包,我是PL / SQL的初学者,使用这样一个全面的软件包对我来说有点复杂。此外,它是级联更新,我的情况是重新插入。我很感激任何帮助
答案 0 :(得分:2)
以下Sql语句将对this SqlFiddle中定义的架构执行任务。请注意,我更改了几个字段和表名 - 因为它们与Oracle术语冲突。 SqlFiddle似乎在我的代码中遇到了一些问题,但它已经在另一个(两栖)客户端上进行了测试,该客户端仍然是无名的。
关键点(正如我在评论中所说)是推导出将旧序列号映射到新序列的规则。视图SEQUENCE_MAP
在以下查询中执行此任务。
您可能对我的回复感到失望,因为它取决于与LIST/LIST_DETAILS
存在完全相同的序列记录数,因此它只能运行一次。我希望你的最终PL / SQL可以执行必要的检查。
希望这是一个改进sequence_map
逻辑的问题,让你到达你想去的地方。
避免使用游标;理想情况下,在操作关系数据时,您需要根据数据集而不是行进行思考。这是因为如果你使用集合思维,Oracle可以在优化,并行化等方面发挥其魔力。 Oracle在扩展方面非常出色 - 例如,如果一个表分散在多个磁盘上,它可能会同时处理来自多个磁盘的数据的请求。如果你强制它逐行,程序逻辑,你可能会发现你编写的应用程序不能很好地扩展。
CREATE OR REPLACE VIEW SEQUENCE_MAP AS (
SELECT OLD_SEQ, NEW_SEQ FROM
(
( SELECT ROWNUM AS RN, SUP_ID AS OLD_SEQ FROM
(SELECT SUP_ID FROM LIST ORDER BY SUP_ID) ) O
JOIN
( SELECT ROWNUM AS RN, SUP_ID AS NEW_SEQ FROM
(SELECT SEQ AS SUP_ID FROM SEQUENCE_TABLE ORDER BY SEQ) ) N
ON N.RN = O.RN
)
);
INSERT INTO LIST
(
SELECT
NEW_SEQ, SUB_NAME, SUB_CODE
FROM
SEQUENCE_MAP
JOIN LIST L ON
L.SUP_ID = SEQUENCE_MAP.OLD_SEQ
);
INSERT INTO LIST_DETAILS
(
SELECT
BUY_ID, NEW_SEQ, SUB_DETAIL, MAX_FIELD, MIN_FIELD
FROM
SEQUENCE_MAP
JOIN LIST_DETAILS L ON
L.SUP_ID = SEQUENCE_MAP.OLD_SEQ
);
答案 1 :(得分:1)
我会做2个内循环,并搜索下一个要使用的序列。
我想新的buy_id是通过触发器使用序列或类似的东西来分配的,否则你必须在你的代码中生成它。
我没有可用的Oracle数据库来测试它,所以不要注意语法。
DECLARE
NEW_Sup_ID Sup_ID%type := Seq;
c_Sup_ID Sup_ID%type := Seq;
c_Sup_Name Sup_Name%type;
c_Sup_Code Sup_Code%type;
c_Buy_ID Buy_ID%type;
c_Sup_Detail Sup_Detail%type;
c_Max_Amount Max_Amount%type;
c_My_Min_Amount Min_Amount%type;
CURSOR c_My_List
IS
SELECT * FROM My_List;
CURSOR c_My_List_details
IS
SELECT * FROM My_List_details where sup_id=c_Sup_ID;
BEGIN
for c_My_List IN c_Sup_ID, c_Sup_Name, c_Sup_Code loop
select min(seq) from My_sequence into NEW_Sup_ID;
INSERT INTO My_List (sup_id,...) values (NEW_Sup_ID,...);
for c_My_List_details IN c_Buy_ID, NEW_Sup_ID, c_Sup_Detail, c_Max_Amount, c_Min_Amount loop
INSERT INTO My_List_details (sup_id, ...) values (NEW_Sup_ID,...);
end loop;
deelte from from My_sequence where seq= NEW_Sup_ID;
end loop;
commit;
END;
/