【问题标题】:Retrieve Oracle database name without querying无需查询即可检索 Oracle 数据库名称
【发布时间】:2018-06-22 06:06:27
【问题描述】:

我有两个 Oracle 11gR2 数据库(一个用于测试目的,另一个用于生产)。

通过使用条件编译,我需要创建一个在测试环境中使用数据库链接并且在生产环境中使用数据库链接的函数。

问题是我需要将它放入包体中,这将在两种环境中自动编译。生产环境中不会有这样的数据库链接,所以包不会编译

一种解决方案是创建一个虚拟数据库链接,该链接在生产环境中自行解析(生产 -> 生产),但这肯定不是解决此问题的正确方法。

例如:

DECLARE 
    v_db_name     VARCHAR2(200);
    vt_tbl_data   data_table%ROWTYPE;
BEGIN
    $IF v_db_name = 'TEST' $THEN 
        SELECT tbl.*
          INTO vt_tbl_data
          FROM data_table@otherdb tbl
         WHERE ROWNUM = 1;
    $ELSIF v_db_name = 'PROD' $THEN
        SELECT tbl.*
          INTO vt_tbl_data
          FROM data_table tbl
         WHERE ROWNUM = 1;
    $END
END;
/

【问题讨论】:

  • 自动编译是如何发生的——你有能力改变编译发生的会话吗? (大概架构名称是相同的 - 否则您可以更轻松地检查...)
  • PLSQL_CCFLAGS 可以使用。您可以在测试数据库上执行ALTER SYSTEM SET PLSQL_CCFLAGS = 'env_test:true';,然后使用$IF $$env_test $THEN xxxxxx $ELSE yyyyyy $END。详情请见the documentation。但是我最喜欢同义词的想法。
  • 不,我无法更改编译顺序并更改会话。但是,感谢你们两位的 cmets。直到现在才知道 PLSQL_CCFLAGS。

标签: database oracle plsql oracle11g conditional-compilation


【解决方案1】:

你的包体中没有数据库链接语法。在两种环境中创建同义词并在包正文中引用同义词。

这样你的包体在两个环境中是相同的——只有同义词的定义不同。

【讨论】:

    【解决方案2】:

    如果您可以更改编译会话 - 在任一环境或两种环境中 - 您可以使用 a compilation flag via PLSQL_CCFLAGS:

    alter session set PLSQL_CCFLAGS = 'has_db_link:TRUE';
    
    DECLARE 
        vt_tbl_data   data_table%ROWTYPE;
    BEGIN
        $IF $$has_db_link $THEN 
            SELECT tbl.*
              INTO vt_tbl_data
              FROM data_table@otherdb tbl
             WHERE ROWNUM = 1;
        $ELSE
            SELECT tbl.*
              INTO vt_tbl_data
              FROM data_table tbl
             WHERE ROWNUM = 1;
        $END
    END;
    /
    

    或重复较少,但可能更难遵循:

    DECLARE 
        vt_tbl_data   data_table%ROWTYPE;
    BEGIN
        SELECT tbl.*
          INTO vt_tbl_data
        $IF $$has_db_link $THEN 
          FROM data_table@otherdb tbl
        $ELSE
          FROM data_table tbl
        $END
         WHERE ROWNUM = 1;
    END;
    /
    

    如果您将标志设置为FALSE,或者根本不设置它,那么在生产中它只会编译$ELSE 分支。

    您无法将标志设置为字符串,因此您无法测试特定名称;但无论如何,真/假对我来说似乎更直观。

    如果您无法更改编译的发生方式以更改会话,您可能会通过登录触发器来执行此操作 - 在这种情况下可能仅在测试环境中,并且可能使用更通用的标志名称,如 @ 987654327@@krokodilko 建议。

    【讨论】:

    • 感谢您的回答,但我无法更改编译的方式。我相信你的回答也可以帮助其他人。
    猜你喜欢
    • 2011-09-11
    • 1970-01-01
    • 1970-01-01
    • 2019-02-02
    • 2013-01-10
    • 1970-01-01
    • 2012-02-17
    • 2014-12-25
    • 2014-06-29
    相关资源
    最近更新 更多