选择*通过dblink

时间:2011-05-17 13:42:15

标签: oracle plsql cursor dblink

尝试通过循环游标来更新表时遇到一些麻烦,该游标通过dblink从源表中选择。

我有两个数据库DB1,DB2。

它们是两个不同的数据库实例。 我在DB1中使用以下语句:

CURSOR TestCursor IS
    SELECT  a.*, 'A' TEST_COL_A, 'B' TEST_COL_B
    FROM rpt.SOURCE@DB2  a;
BEGIN
    For C1 in TestCursor loop
        INSERT into  RPT.TARGET 
        (

           /*The company_name and cust_id are select from SOURCE table from DB2*/  
           COMPANY_NAME, CUST_ID, TEST_COL_A, TEST_COL_B

        ) 
        values
        (  
           C1.COMPANY_NAME, C1.CUST_ID, C1.TEST_COL_A , C1.TEST_COL_B
        ) ;

    End loop;

    /*Some code...*/

End

在向SOURCE表@ DB2

添加“NEW_COL”列之前,一切正常

插入数据的值不正确。

正如我所料,TEST_COL_A的值应为'A'。

但是,它包含我在SOURCE表中添加的NEW_COL的值。

TEST_COL_B的值包含'A'。

有没有人遇到同样的问题? 似乎oracle在编译时缓存了表列。 有没有办法在不重新编译的情况下将列添加到源表?

2 个答案:

答案 0 :(得分:1)

根据this

  

Oracle数据库无法管理   远程模式之间的依赖关系   除了以外的对象   本地程序到远程过程   的依赖关系。

     

例如,假设是本地视图   由查询创建和定义   引用远程表。还假设   本地过程包括SQL   引用相同的语句   远程表。后来的定义   桌子被改变了。

     

因此,本地视图和   程序永远不会失效,甚至   如果之后使用视图或过程   表被改变了,即使是   视图或过程现在返回错误   使用时在这种情况下,视图或   程序必须手动更改,以便   不返回错误。在这样的   案例,缺乏依赖管理   是不必要的   依赖对象的重新编译。

在这种情况下,你并没有看到错误,但原因是一样的。如果使用显式列名而不是*,也不会有问题,这通常更安全。如果您正在使用*,则无法避免重新编译(除非,我认为*是选择列表中的最后一项,在这种情况下,末尾的任何额外列都不会导致一个问题 - 只要他们的名字没有发生冲突。)

答案 1 :(得分:0)

我建议您在DB1中使用单个集合处理插入语句,而不是一次在游标处为插入循环使用一行,例如:

INSERT into  RPT.TARGET 
select COMPANY_NAME, CUST_ID, 'A' TEST_COL_A, 'B' TEST_COL_B
FROM rpt.SOURCE@DB2
;

理论价格:

  1. 设置处理几乎总是一次执行一次 处理(这确实是一次很慢的处理)。
  2. 设置插入处理集是可扩展的解决方案。如果应用程序需要扩展到成千上万行或数百万行,则一次行解决方案将不太可能扩展。
  3. 此外,由于您的原因,使用select *构造也很危险 遇到[和其他类似原因]。