【问题标题】:Dynamic DBLink in OracleOracle 中的动态 DBLink
【发布时间】:2014-12-17 21:07:37
【问题描述】:

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

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

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

SELECT * FROM my_tbl_s;

这可行,但是我想在包中使用它,所以当我执行创建同义词时,包无效。我还尝试将我的代码分成不同的包并在同义词更新后重新编译:

EXECUTE IMMEDIATE 'ALTER PACKAGE my_pck COMPILE';   

但是,原来的调用包还是失效了。谁能想到不使用动态 SQL 来实现动态 DB Links 的方法?

【问题讨论】:

  • 实际上,我认为同样的概念可以使用 VIEWS 而不是 SYNONYM。我不相信更新视图会使引用包无效。需要测试...

标签: oracle plsql oracle10g dblink


【解决方案1】:

如果我是你,我会改变对动态 SQL 的态度。相反,您尝试做的并不比将查询存储在字符串中更容易。

动态 DDL 可能(理论上)保持您的 SQL 静态,但是,它有一个主要缺陷是单独破坏交易 - 它不是事务性的,这意味着每次调用 @987654321 @ - 你承诺。

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

我什至没有提到你已经遇到的依赖失效。

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

create view tab as 
select 1 as dblink, t.* as tab@dblink1 union all
select 2 as dblink, t.* as tab@dblink2

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

需要考虑很多复杂的东西,实际上你不应该通过 DBMS 的设计来考虑这些东西,很多东西都有可能被破坏。字符串处理要容易得多,更重要的是,在这些情况下,这是您应该设计的。

【讨论】:

    【解决方案2】:

    我还使用另一个数据库中的对象的同义词,只是为了清楚和记录。而且我们确实更改了数据库链接,但从脚本而不是从 PL/SQL,所以我们没有遇到包重新编译问题。

    话虽如此,我会考虑将其分成两个包。

    1. 使用数据库链接的包,也就是你已经拥有的包。

    2. “链接更改程序包”,具有更改链接的过程(使用EXECUTE IMMEDIATE),然后重新编译程序包 1(或所有无效程序包或依赖该链接的所有程序包)。

    这会起作用还是我们会进入失效依赖循环?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-23
      • 2015-07-27
      • 1970-01-01
      • 1970-01-01
      • 2012-01-21
      • 1970-01-01
      • 2014-03-27
      相关资源
      最近更新 更多