暂无图片
暂无图片
2
暂无图片
暂无图片
暂无图片

使用本地函数DML操作远程表时报错ORA-02069

环境

  • 源端
db_name                              string                            gbkdb
db_unique_name                       string                            gbkdbdr
global_names                         boolean                           FALSE
复制
SQL> conn scott/tigger Connected. Create function myFunction ( inParameter in PLS_INTEGER ) return VARCHAR2 is Begin Return '0'; End myFunction; / Create database link ORC2 connect to scott Identified by tigger using 'linux8:1521/utf8db';
复制
  • 目标端
db_name                              string      utf8db
db_unique_name                       string      utf8db
global_names                         boolean     FALSE
复制
SQL> conn scott/tigger Connected. SQL> SQL> create table test123 (t1 number,t2 varchar2(10)); Table created.
复制

问题复现

源端

普通插入

SQL> insert into test123@ORC2(t1,t2) values(999, to_char ( 1 ) ); 1 row created. SQL> commit; Commit complete. SQL>
复制

调用函数后插入

SQL> insert into test123@ORC2(t1,t2) values(999, myFunction ( 1 ) ); insert into test123@ORC2(t1,t2) values(999, myFunction ( 1 ) ) * ERROR at line 1: ORA-02069: global_names parameter must be set to TRUE for this operation SQL> alter session set global_names=true; Session altered. SQL> insert into test123@ORC2(t1,t2) values(999, myFunction ( 1 ) ); insert into test123@ORC2(t1,t2) values(999, myFunction ( 1 ) ) * ERROR at line 1: ORA-02085: database link ORC2 connects to UTF8DB SQL>
复制
02069, 00000, "global_names parameter must be set to TRUE for this operation"
// *Cause: A remote mapping of the statement is required but cannot be achieved
//         because global_names should be set to TRUE for it to be achieved
// *Action: Issue alter session set global_names = true if possible

SQL> !oerr ora 2085
02085, 00000, "database link %s connects to %s"
// *Cause: a database link connected to a database with a different name.
//  The connection is rejected.
// *Action: create a database link with the same name as the database it
//  connects to, or set global_names=false.
//

SQL> 
复制

问题解决

  • 根据MOS文章:

Ora-02069 When Using a Local Function While Updating a Remote Table (Doc ID 342320.1)
由于限制,在对远程表执行dml操作时不可能使用本地函数。当尝试这样做时,会引发ORA-02069。

以下是避免上述场景中ora-2069错误的可能解决方案

1.使用global_names = true。

这可以在会话的基础上完成:“alter session set global_names=true”。
复制

2.将要使用的功能放在远程站点。

3.在远程站点上放置一个包装器函数,该函数通过数据库链接将实际函数调用回本地站点。

4.包含“from” “dual”表。将有一个笛卡尔积(with dual),函数将在调用端应用,因此可能会出现一些性能问题。

  • 根据MOS文章:

Click to add to Favorites Inserting Data To View Mapped Via Dblink To Remote Table Returns Ora-02069 (Doc ID 467787.1)
注意:ORA-02069错误消息显示了解决方案的一部分,“global_names参数必须设置为TRUE”,但这还不够,接下来的部分将有助于理解根本原因,以及完整的解决方案。

Global_names未设置为true。远程数据库上不存在到本地数据库的数据库链接。

在此场景中,需要以下内容才能使插入语句工作:

  1. Global_names设置为true。

  2. 到本地数据库的数据库链接必须在远程数据库上存在。

当调用与插入语句内联的PLSQL函数时。它需要执行并通过数据库链接(本地链接)将输出返回给远程会话。在插入之后,远程会话将需要向本地数据库发送确认,因此需要远程站点上的另一个数据库链接连接到本地数据库。

因此,必须将global_names设置为true,这使oracle能够自动检测远程数据库链接名称,该名称将与本地数据库名称相同(仅当global_names设置为true时才会出现这种情况)。

ORA-02085解决(GLOBAL_NAMES设置为true时触发)

根据MOS文章:
Database Links: Troubleshooting ORA-2085: database link %s connects to %s (Doc ID 210630.1)

当源数据库初始化参数GLOBAL_NAMES设置为true时

数据库链接名称必须与目标数据库全局名称匹配,因为它存在于GLOBAL_NAME中:

  • 目标端
select * from global_name; GLOBAL_NAME -------------------- UTF8DB
复制
  • 源端
SQL> alter session set global_names=true; Session altered. SQL> select * from dual@ORC2; select * from dual@ORC2 * ERROR at line 1: ORA-02085: database link ORC2 connects to UTF8DB SQL> SQL> Create database link utf8db connect to scott Identified by tigger using 'linux8:1521/utf8db'; Database link created. SQL> select * from dual@utf8db; D - X SQL>
复制

ORA-02019解决

  • 源端dblink创建好后
SQL> insert into test123@UTF8DB(t1,t2) values(999, myFunction ( 1 ) ); insert into test123@UTF8DB(t1,t2) values(999, myFunction ( 1 ) ) * ERROR at line 1: ORA-02019: connection description for remote database not found ORA-02063: preceding line from UTF8DB
复制
  • 目标端创建dblink
SQL> Create database link gbkdb connect to scott Identified by tigger using 'linux8:1521/gbkdbdr'; Database link created.
复制
  • 源端插入成功
SQL> insert into test123@UTF8DB(t1,t2) values(999, myFunction ( 1 ) ); 1 row created.
复制

订阅号:DongDB手记
墨天轮:https://www.modb.pro/u/231198

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
1人已赞赏
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论