通过 dblink 选择 *

Posted

技术标签:

【中文标题】通过 dblink 选择 *【英文标题】:select * through dblink 【发布时间】:2011-05-17 13:42:14 【问题描述】:

我在尝试通过 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

在我将“NEW_COL”列添加到 SOURCE table@DB2 之前,一切正常

插入数据的值错误。

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

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

并且 TEST_COL_B 的值包含 'A'。

有人遇到过同样的问题吗? 似乎 oracle 在编译时缓存了表列。 有什么方法可以在不重新编译的情况下向源表添加列?

【问题讨论】:

您没有尝试指定严格的列列表(a.COMPANY_NAME、a.CUST_ID)而不是 a.* 吗? REMOTE_DEPENDENCY_MODE 的设置是什么?它可以是SIGNATURETIMESTAMP,每个都会导致不同的问题;-) 另外使用* 也不是一件好事,请尝试使用@heximal 提及的显式列名。 @amep: REMOTE_DEPENDENCY_MODE 仅适用于远程过程,不适用于表。 你试过在你的 SQL 中使用 NOCACHE 提示吗?好奇缓存是否是您的问题(?) 【参考方案1】:

根据this:

Oracle 数据库不管理 远程模式之间的依赖关系 以外的物体 本地程序到远程程序 依赖关系。

例如,假设本地视图 由一个查询创建和定义 引用远程表。还假设 本地过程包含 SQL 引用相同的语句 远程表。后来的定义 表已更改。

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

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

【讨论】:

感谢您的帮助!这些是我们数据库中的一些现有代码,现在我认为是时候更改代码了。 :p【参考方案2】:

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

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

理由:

    Set 处理几乎总是会超过一次执行 Row-at-a-time 处理[这真的是一次很慢的处理]。 设置处理插入是一种可扩展的解决方案。如果应用程序需要扩展到数万行或数百万行,那么一次一行的解决方案可能无法扩展。 另外,使用select * 构造是危险的,因为你 遇到[和其他类似原因]。

【讨论】:

以上是关于通过 dblink 选择 *的主要内容,如果未能解决你的问题,请参考以下文章

为啥不能通过 DBLink 发送 Oracle XMLType?

oracel 通过dblink 调用mssql 存储过程

Oracle SQL:通过 dblink 加入

你可以通过 DBLink 出列吗?

oracle通过DBlink连接oracle

expdp通过dblink远端导出