在 DBLINK 中作为循环插入或更新

问题描述

我有一行,我想从另一个带有 DBLINK 的模式插入(或更新,如果 ID 已被使用)。这个表有很多 FK,所以我需要更新或插入(如果不存在)大约 20 个表。

我尝试将来自 DBLINK 的不同表中所有需要的行写入变量,然后检查目标表是否已经有这些行。我确信有一种更简单的方法来做到这一点。一个循环,其中表及其行类型保存在集合中,例如立即执行,但我找不到任何东西。

这个例子在我的代码中出现了 20 次,我确信有一个更简单的方法来做到这一点,然后一遍又一遍地写。

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,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 和循环)来做到这一点。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)