Loops 在数据库链接中作为循环插入或更新
我有一行,我不想从另一个带有DBLINK的模式中插入(或者更新,如果已经使用了ID)。这个表有很多FK,所以我需要更新或插入(如果不存在)大约20个表 我尝试将DBLINK中不同表中所有需要的行写入变量,然后检查目标表是否已经有这些行。我相信有一个更简单的方法来做这件事。一个循环,其中表及其行类型保存在一个集合中,例如execute immdediate,但我找不到任何内容 这个例子在我的代码中出现了20次,我确信有一种更简单的方法可以做到这一点,然后一遍又一遍地写下去Loops 在数据库链接中作为循环插入或更新,loops,plsql,collections,dblink,Loops,Plsql,Collections,Dblink,我有一行,我不想从另一个带有DBLINK的模式中插入(或者更新,如果已经使用了ID)。这个表有很多FK,所以我需要更新或插入(如果不存在)大约20个表 我尝试将DBLINK中不同表中所有需要的行写入变量,然后检查目标表是否已经有这些行。我相信有一个更简单的方法来做这件事。一个循环,其中表及其行类型保存在一个集合中,例如execute immdediate,但我找不到任何内容 这个例子在我的代码中出现了20次,我确信有一种更简单的方法可以做到这一点,然后一遍又一遍地写下去 PROCEDURE Te
PROCEDURE Test_copy (pi_id IN NUMBER) IS
V_REC_Table1 Table1%ROWTYPE;
V_REC_Table2 Table2%ROWTYPE;
V_REC_Table3 Table3%ROWTYPE;
V_REC_Table4 Table4%ROWTYPE;
V_REC_Table5 Table5%ROWTYPE;
V_REC_Table6 Table6%ROWTYPE;
V_REC_Table7 Table7%ROWTYPE;
V_REC_Table8 Table8%ROWTYPE;
V_REC_Table9 Table9%ROWTYPE;
V_REC_Table10 Table10%ROWTYPE;
V_REC_Table1_exists Table1%ROWTYPE;
V_REC_Table2_exists Table2%ROWTYPE;
V_REC_Table3_exists Table3%ROWTYPE;
V_REC_Table4_exists Table4%ROWTYPE;
V_REC_Table5_exists Table5%ROWTYPE;
V_REC_Table6_exists Table6%ROWTYPE;
V_REC_Table7_exists Table7%ROWTYPE;
V_REC_Table8_exists Table8%ROWTYPE;
V_REC_Table9_exists Table9%ROWTYPE;
V_REC_Table10_exists Table10%ROWTYPE;
v_sql VARCHAR2(2000);
Begin
v_sql := 'SELECT * FROM Table1@dblink WHERE ID = '||pi_id;
EXECUTE IMMEDIATE v_sql INTO V_REC_DBLINK_Table1;
Exception
when no_data_found then
Raise_application_Error(-20001, 'ID doesnt exist');
END;
Begin
v_sql := 'SELECT * FROM Table2@dblink WHERE ID = '||V_REC_Table1.T2_ID;
EXECUTE IMMEDIATE v_sql INTO V_REC_DBLINK_Table2;
Exception
when no_data_found then
Raise_application_Error(-20001, 'ID doesnt exist');
END;
(and so on)
.
.
.
BEGIN
v_sql := 'SELECT * FROM Table1 WHERE ID = '||V_REC_DBLINK_TABLE1.ID;
EXECUTE IMMEDIATE v_sql INTO V_REC_DBLINK_TABLE1_EXISTS;
UPDATE TABLE1
SET ID = V_REC_DBLINK_Table1.ID,
NAME = V_REC_DBLINK_Table1.NAME,
DESCRIPTION = V_REC_DBLINK_Table1.DESCRIPTION
NOTE = V_REC_DBLINK_Table1.NOTE
NUMBER = V_REC_DBLINK_Table1.NUMBER
ADDRESS = V_REC_DBLINK_Table1.ADDRESS
WHERE ID = V_REC_DBLINK_TABLE1.ID;
EXCEPTION
when no_data_found then
INSERT INTO TABLE1
(ID, NAME, DESCRIPTION, NOTE, NUMBER, ADDRESS)
Values(V_REC_DBLINK_TABLE1.ID
,V_REC_DBLINK_TABLE1.NAME
,V_REC_DBLINK_TABLE1.DESCRIPTION
,V_REC_DBLINK_TABLE1.NOTE
,V_REC_DBLINK_TABLE1.NUMBER
,V_REC_DBLINK_TABLE1.ADDRESS);
END;
BEGIN
v_sql := 'SELECT * FROM Table2 WHERE ID = '||V_REC_DBLINK_TABLE2.ID;
EXECUTE IMMEDIATE v_sql INTO V_REC_DBLINK_TABLE2_EXISTS;
UPDATE TABLE2
SET ID = V_REC_DBLINK_Table2.ID,
NAME = V_REC_DBLINK_Table2.NAME,
DESCRIPTION = V_REC_DBLINK_Table2.DESCRIPTION
WHERE ID = V_REC_DBLINK_TABLE2.ID;
EXCEPTION
when no_data_found then
INSERT INTO TABLE2
(ID, NAME, DESCRIPTION)
Values(V_REC_DBLINK_TABLE2.ID
,V_REC_DBLINK_TABLE2.NAME
,V_REC_DBLINK_TABLE2.DESCRIPTION);
END;
(and so on for all Tables via DBLINK)
有什么建议吗?我只想用一种较短的方式(可能通过Collection和loop)实现这一点。查看MERGE语句。这正是您在一条sql语句中所需要的。有一些触发器阻止我使用MERGE,并且一秒钟内不允许Im禁用它们。MERGE only使上面显示的查询更容易,但它不能帮助我解决我的主要问题,使我使用的表可以更改,这样我就可以编写一个循环,在这个循环中,我只更改表的名称(和行类型)以将其转换为EXECUTE IMMEDIATE。您能提供一些详细信息吗?现在还不清楚你想要实现什么。您要求存储表名和行类型,但代码中没有行类型引用。请提供完整的表定义。尤其是需要更改行类型的目标表?只是列顺序,但名称相同吗?另外,以文本形式提供示例数据-没有涵盖每个条件的图像,以及该数据的预期结果。注意:没有阻止使用合并的触发器。它将根据需要触发任何插入或更新(甚至删除)触发器。最后,当前更新不会更改任何数据;Update table2 set id=table2.id结构与Update table2 set id=id结构完全相同,其他列的结构也完全相同。