【问题标题】:In Oracle DB how to avoid decompiling of objects dependent on a DBLink?在 Oracle DB 中如何避免反编译依赖于 DBLink 的对象?
【发布时间】:2021-08-16 19:14:54
【问题描述】:

有一个到远程数据库的 DBLink 和一个包 MY_PACKAGE(在本地模式中)通过 MY_VIEW 间接依赖于它。

当 DBLink 无效(无论出于何种原因,即连接丢失或远程凭据被更改)时,包将变为无效。但是让它工作会很棒,因为这个包除了通过这个 DBLink 进行协商之外还有其他职责。总的来说,我不认为模式对象的有效性取决于网络连接等不稳定部分。

我在遗留代码中发现了这种情况(参见MY_PACKAGE.doSomething()),我什至不确定这是否是正确的设计。您能对此发表您的看法吗?

即使某些 DBLink 不可用,将包保持在 VALID 状态的正确方法是什么?

例如,使用引用MY_VIEW 的动态游标是否正确,仅当DBLink 不正常时(即MY_PACKAGE.doSomethingAgain())才无法打开。当然,也许有一个更自然的方法来解决这个问题。我很高兴听到所有适合在 Oracle 中安全使用 DBLinks 的选项。

代码:

-- DBLink --------------------------------------------------------------
CREATE DATABASE LINK "MY_LINK"
CONNECT TO "MY_USER" IDENTIFIED BY VALUES ':1' USING 'WHATEVER';
------------------------------------------------------------------------

-- Synonym -------------------------------------------------------------
CREATE OR REPLACE EDITIONABLE SYNONYM "MY_SYNONYM" 
FOR "MY_REMOTE_SCHEMA"."MY_REMOTE_VIEW"@"MY_LINK";
------------------------------------------------------------------------

-- View ----------------------------------------------------------------
CREATE OR REPLACE VIEW "MY_VIEW" AS 
SELECT a,b,c FROM "MY_SYNONYM";

> Compiler Error    
>   ORA-02063: preceding 2 lines from MY_LINK
>  ORA-01017: invalid username/password; logon denied
>  [Oracle][ODBC SQL Server Wire Protocol driver][SQL Server]
>  Login failed for user 'MY_USER'. {28000,NativeErr = 18456}
------------------------------------------------------------------------

.

-- Package body --------------------------------------------------------
CREATE OR REPLACE PACKAGE BODY MY_PACKAGE AS
  
    PROCEDURE doSomething()
    IS
      i NUMBER := 0;
    BEGIN  
      FOR rec IN (SELECT * FROM "MY_VIEW")
      LOOP
        i := i + 1;
      END LOOP;
    END;
  
    PROCEDURE doSomethingAgain()
    IS
      i NUMBER := 0;
      my_cur SYS_REFCURSOR;
    BEGIN  

      OPEN my_cur FOR 'SELECT * FROM MY_VIEW';
      
      LOOP
        FETCH my_cur -- ...

        -- etc ...

        i := i + 1;
      END LOOP;
    END;
END MY_PACKAGE;

> Compiler Error
> 7/4   PL/SQL: SQL Statement ignored
> 7/35  PL/SQL: ORA-04063: view "MY_VIEW" has errors
------------------------------------------------------------------------

【问题讨论】:

    标签: oracle plsql database-design dblink


    【解决方案1】:

    我想,最好的选择是让数据库链接保持活跃。


    另一种选择是移动使用那些可疑数据库链接的过程 - 移出该程序包,并使它们成为独立的存储过程,这样如果它们变得无效,只有 它们 无效(而不是整个包),或者 - 可能 - 将那些程序(具有相同命运)放入单独的包中。


    另一个选择是使用动态 SQL,因为 Oracle 不关心所涉及的任何对象是否有效,直到您实际尝试使用它们。像这样的:

    SQL> create database link my_link
      2  connect to whoever
      3  identified by whatever
      4  using 'database_that_does_not_exist';
    
    Database link created.
    
    SQL> create or replace view my_view as
      2  select * from some_table@my_link;
    select * from some_table@my_link
                             *
    ERROR at line 2:
    ORA-12154: TNS:could not resolve the connect identifier specified
    
    
    SQL> create or replace procedure my_proc as
      2    l_id number;
      3  begin
      4    select id into l_id
      5    from my_view;
      6  end;
      7  /
    
    Warning: Procedure created with compilation errors.
    
    SQL> show err
    Errors for PROCEDURE MY_PROC:
    
    LINE/COL ERROR
    -------- -----------------------------------------------------------------
    4/3      PL/SQL: SQL Statement ignored
    5/8      PL/SQL: ORA-00942: table or view does not exist
    

    但是,使用动态 SQL:

    SQL> create or replace procedure my_proc as
      2    l_id number;
      3  begin
      4    execute immediate 'select id from my_view' into l_id;
      5  end;
      6  /
    
    Procedure created.
    
    SQL>
    

    看起来不错,但时间不长:

    SQL> exec my_proc;
    BEGIN my_proc; END;
    
    *
    ERROR at line 1:
    ORA-00942: table or view does not exist
    ORA-06512: at "SCOTT.MY_PROC", line 4
    ORA-06512: at line 1
    
    
    SQL>
    

    是的,我知道 - 并非所有代码都简单到可以将其放入动态 SQL 中。它越大,你必须维护它的问题就越严重,所以这只是我真的不想使用的可能性。

    【讨论】:

      猜你喜欢
      • 2020-04-06
      • 1970-01-01
      • 2015-01-14
      • 2013-08-22
      • 2014-12-08
      • 1970-01-01
      • 1970-01-01
      • 2017-01-02
      • 1970-01-01
      相关资源
      最近更新 更多