尝试通过循环游标来更新表时遇到一些麻烦,该游标通过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在编译时缓存了表列。 有没有办法在不重新编译的情况下将列添加到源表?
答案 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
;
理论价格:
select *
构造也很危险
遇到[和其他类似原因]。