【问题标题】:How to use synonym of a DBlink in Oracle?如何在 Oracle 中使用 DBlink 的同义词?
【发布时间】:2015-12-01 09:45:58
【问题描述】:

我为 dblink 创建了同义词。

create synonym dblink2 for dblink1

但是当我使用同义词而不是 dblink 查询任何内容时,我收到 connection description for remote database not found 错误。

SELECT * FROM DUAL@DBLINK2

如何使用同义词进行查询?

编辑:我知道如果我使用 dblink 创建表视图,它会起作用。但我的要求是上面的问题。

【问题讨论】:

  • 为远程数据库中的表创建同义词比为 dblink 本身创建同义词更有意义。例如:create synonym dual_dblink2 for dual@dblink1
  • 100 个表。无法创建 100 个同义词。
  • 你实际上不能按照你的要求去做。你为什么要这样做?与创建指向同一个地方的不同名称的 db_link 相比,似乎没有明显的优势,即使这似乎是一个奇怪的要求。如果你解释一下你为什么想要这个,有人可能会提出一个同样有效的替代解决方案。
  • 100 同义词到底有什么问题?我的意思是您关心对象的数量还是只关心创建对象所需的时间?
  • @Nitish,您可以在数据库中定义的同义词数量几乎没有限制。如果您的数据库有 100 个表,那么没有什么能阻止您创建 100 个同义词。

标签: oracle dblink


【解决方案1】:

很遗憾,不支持为 dblinks 创建同义词。如果你阅读documentation on synonyms,你会发现同义词的允许对象只有:

使用 CREATE SYNONYM 语句创建同义词,它是 表、视图、序列、过程、存储的替代名称 函数、包、物化视图、Java 类模式对象、 用户定义的对象类型,或其他同义词

您的第二个查询失败的原因是您创建的同义词无法正常运行。 在创建时未正确验证它,您可以创建任何类型的错误同义词,例如.要验证,只需测试以下语句:

create synonym dblink3 for no_object_with_this_name;

你仍然会得到这样的回应:

*Synonym DBLINK3 created.*

当然,通过这个同义词没有任何作用。

【讨论】:

  • 我的回答并未表明有可能。我的回答只表明你可以成功运行一个给你的印象是你已经创建了一个的语句。我在那里添加了那部分以指出为什么它看起来可能对@Nitish。我猜他肯定会对此感兴趣。
  • 那么为什么 Oracle 允许这样的特性呢?不应该有验证吗?有这个功能有什么好处吗?
  • 这并不是真正的“功能”,而是设计决策。 Oracle 在编译时并没有真正验证同义词的创建。我想这是有道理的,因为即使在成功创建后它也会失效。想象有一个同义词通过 dblink 指向远程数据库中的一个表。然后该表被删除。远程数据库没有简单的方法来阻止它,因此现有的同义词变得无效。这将是在访问时验证同义词的一个很好的理由。
【解决方案2】:

我看不出为 dblink 本身创建同义词的意义。理想情况下,您使用 dblink远程表 创建 同义词

CREATE DATABASE LINK my_db_link CONNECT TO user IDENTIFIED BY passwd USING 'alias';
CREATE SYNONYM my_table FOR remote_table@my_db_link;

现在,您可以使用同义词查询远程表

SELECT * FROM my_table;

【讨论】:

    【解决方案3】:

    我正在考虑通过在 db_link 上放置同义词来解决的业务问题,而我唯一能想到的是您需要部署将从 some_Table@some_dblink 中选择的常量代码,并且尽管表名是不变的,但不同的用户可能正在查看不同的 db_links。或者您只是希望能够通过一个简单的同义词重新指向来交换您正在操作的 db_link。

    问题是:不能那样做。不允许使用 db_link 同义词。

    您唯一的解决方案是让代码通过同义词引用表,并将私有同义词设置为指向正确的 db_link。这样,您的代码将继续“从 REMOTE_TABLE1 中选择”,您只需翻转从哪个 DB_LINK 获取该远程表。

    必须设置/重置 100 多个私有同义词是否很痛苦?是的。但是,如果这是您需要经常做的事情,那么请捆绑一个过程来为您做这件事,您可以在其中传入 db_link 名称,它会循环并为您重置同义词。

    【讨论】:

      【解决方案4】:

      如果您试图让多个模式(用户)可以访问数据库链接,答案是创建一个 public 数据库链接

      示例:

      CREATE PUBLIC DATABASE LINK dblink1 CONNECT TO user IDENTIFIED BY password USING 'tnsalias';
      

      之后任何架构都可以发出:

      SELECT * FROM TABLE@dblink1
      

      【讨论】:

        【解决方案5】:

        虽然我知道这个问题已有 3 年以上的历史,但将来有人可能会从不同的答案中受益。

        假设我有 4 个数据库,2 个用于生产,2 个用于开发/测试。

        产品数据库:PRDAPP1DB1 和 PRDAPP2DB1 开发数据库:DEVAPP1DB1 和 DEVAPP2DB1

        “APP2”数据库正在运行从 APP1 数据库中提取和导入数据的程序。在这些过程中,有各种选择语句,例如:

        declare
        iCount INTEGER;
        begin
          insert into tbl_impdata1
          select sysdate, col1, col2, substr(col3,1,10), substr(col3,15,3)
          from tbl1@dblink2; -- Where dblink2 points to DEVAPP1DB1
          ...
          <more statements here>
          ...
        EXCEPTION
          <exception handling code here>
        end;
        

        现在这对于开发来说没问题,但是在将更新的过程部署到生产环境时,dblink2 需要不断更改为 dblink1。

        如前所述,同义词不能用于此目的。 但是,创建具有相同名称、不同连接字符串的数据库链接。

        例如在生产中:

        CREATE DATABASE LINK "MyDBLINK" USING 'PRDAPP1DB1';
        

        在开发上:

        CREATE DATABASE LINK "MyDBLINK" USING 'DEVAPP1DB1';
        

        然后在程序中,将所有“@dblink1”和“@dblink2”更改为“@mydblink”,这一切都应该是透明的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-10-15
          • 2012-09-19
          • 2021-09-17
          • 1970-01-01
          • 1970-01-01
          • 2013-05-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多