Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Loops 在数据库链接中作为循环插入或更新_Loops_Plsql_Collections_Dblink - Fatal编程技术网

Loops 在数据库链接中作为循环插入或更新

Loops 在数据库链接中作为循环插入或更新,loops,plsql,collections,dblink,Loops,Plsql,Collections,Dblink,我有一行,我不想从另一个带有DBLINK的模式中插入(或者更新,如果已经使用了ID)。这个表有很多FK,所以我需要更新或插入(如果不存在)大约20个表 我尝试将DBLINK中不同表中所有需要的行写入变量,然后检查目标表是否已经有这些行。我相信有一个更简单的方法来做这件事。一个循环,其中表及其行类型保存在一个集合中,例如execute immdediate,但我找不到任何内容 这个例子在我的代码中出现了20次,我确信有一种更简单的方法可以做到这一点,然后一遍又一遍地写下去 PROCEDURE Te

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

我尝试将DBLINK中不同表中所有需要的行写入变量,然后检查目标表是否已经有这些行。我相信有一个更简单的方法来做这件事。一个循环,其中表及其行类型保存在一个集合中,例如execute immdediate,但我找不到任何内容

这个例子在我的代码中出现了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, 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结构完全相同,其他列的结构也完全相同。