Oracle中的动态DBLink

Pau*_*aul 1 oracle plsql dblink oracle10g

我正在尝试通过在运行时确定的DBLink运行一组查询(来自配置或其他输入).我见过许多建议使用动态SQL和EXECUTE IMMEDIATE的例子.我想不惜一切代价避免这种情况,因为我的查询冗长且可能会发生变化,因此将它们放在字符串中会使维护变得更加困难.

我尝试让我的查询引用同义词,然后在执行查询之前更新同义词:

EXECUTE IMMEDIATE 'CREATE OR REPLACE SYNONYM my_tbl_s FOR my_tbl_t' || p_dblink_name;

SELECT * FROM my_tbl_s;
Run Code Online (Sandbox Code Playgroud)

这是有效的,但我想在一个包中使用它,所以当我执行create synonym时,包无效.我也试过将我的代码分成不同的包并在同义词更新后重新编译:

EXECUTE IMMEDIATE 'ALTER PACKAGE my_pck COMPILE';   
Run Code Online (Sandbox Code Playgroud)

但是,原始调用包仍然无效.谁能想到一种在不使用动态SQL的情况下实现动态DB链接的方法?

Kir*_*tev 5

如果我是你,我会改变对动态SQL的态度.你要做的事情不是让你的生活比在字符串中存储查询更容易.

动态DDL 可能(理论上)保持你的SQL静态,但是,它有一个主要的缺陷,它只是一个交易破坏者 - 它不是事务性的,这意味着,每次你调用execute immediate 'create or replace something'- 你提交.

好吧,说你以某种方式设法使用自治事务处理它 - 然后我们立即面临并发问题:当两个并发事务将尝试覆盖同一个同义词时会发生什么?当有10个时会发生什么?你遇到了瓶颈.

我甚至没有提到你已经遇到过的依赖性失效.

或者您可以使用视图替换表格,例如:

create view tab as 
select 1 as dblink, t.* as tab@dblink1 union all
select 2 as dblink, t.* as tab@dblink2
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您可能会在每次查询该视图时获得N层分布式事务,并且必须确保所有dblink都在线,并且它们的数量必须小于OPEN_LINKS参数,该参数控制最大打开连接数每节课.

需要考虑很多复杂的东西,你实际上不应该考虑DBMS的设计,有很多机会可以破解.字符串处理更容易,更重要的是,在这些情况下,这是您应该通过设计来完成的.