【问题标题】:SQL script behaves differently depending on whether it's run on DB host or from another hostSQL 脚本的行为会有所不同,具体取决于它是在数据库主机上运行还是从另一台主机上运行
【发布时间】:2016-09-23 22:32:52
【问题描述】:

我有一个包含以下内容的 sql 文件: 请注意,v$database 中的 CDB 列仅在版本(不是 Oracle,而是其他一些不相关产品)大于 11 时存在。

当我使用 sqlplus 在数据库主机上执行它时,它运行良好 sqlplus / as sysdba @abc.sql 1000 60 10

但是,当我使用连接字符串远程连接到此数据库主机时,如果 CDB 列不存在(无论我指定什么版本值),它会抱怨“标识符无效”

Connected to: 
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production 
With the Partitioning, Real Application Clusters, Automatic Storage 
Management, Oracle Label Security, 
OLAP, Data Mining, Oracle Database Vault and Real Application Testing options 
. 
old   2:  num_ret_period NUMBER(9) := 
new   2:  num_ret_period NUMBER(9) := 43200; 
old   3:  num_interval NUMBER(9) := 
new   3:  num_interval NUMBER(9) := 60; 
old   5:  lcm_version NUMBER(4) := 
new   5:  lcm_version NUMBER(4) := 1; 
    SELECT CDB INTO isCDB from v$database; 
           * 
ERROR at line 10: 
ORA-06550: line 10, column 12: 
PL/SQL: ORA-00904: "CDB": invalid identifier 
ORA-06550: line 10, column 5: 
PL/SQL: SQL Statement ignored 

任何想法为什么?

DECLARE
 num_ret_period NUMBER(9) := &1;
 num_interval NUMBER(9) := &2;
 isCDB VARCHAR2(10);
 version NUMBER(4) := &3;

BEGIN

  IF version > 11 THEN
    SELECT CDB INTO isCDB from v$database;
    IF (isCDB = 'YES') THEN
      EXECUTE IMMEDIATE 'ALTER session SET CONTAINER = CDB$ROOT';
      dbms_output.put_line('CDB is set to YES');
    ELSE
        dbms_output.put_line('CDB is set to NO');
    END IF;
  END IF;

  callSomeProcedure();

  commit;
EXCEPTION
            when others then
                    dbms_output.put_line('There is an exception in abc.sql' || SQLCODE || ' ' || SQLERRM);
                    ROLLBACK;
                    raise_application_error(-20001, 'There is an exception in abc.sql' || SQLCODE || ' ' || SQLERRM);

    END;
    /

【问题讨论】:

  • 当您说“当我在 DB 主机上执行它时运行良好”时,您是否将 ORACLE_SID(或 TWO_TASK)设置为 12c DB?那么横幅会显示什么?
  • 添加了说明。版本与 Oracle 无关,而是与我通过参数传递的其他产品有关。
  • 数据库版本很重要。它将在 12c 数据库中编译,但不能在 11g 数据库中编译,这是您的输出所显示的。

标签: oracle plsql


【解决方案1】:

即使你不打算执行if version > 11 保护的代码,它仍然需要被解析。此时,CDB 不存在(版本 11)这一事实被揭示。

为避免这种情况,请使用条件编译:

$IF DBMS_DB_VERSION.VER_LE_11 $THEN
   -- version 11 code
   NULL;
$ELSE
   -- version 12 and later code
   NULL;
$END

条件编译指令的作用类似于预处理器。

https://oracle-base.com/articles/10g/conditional-compilation-10gr2

【讨论】:

  • 谢谢,但该版本不适用于 Oracle,而是用于其他一些不相关的产品。
  • @Pha3drus - 您仍然可以围绕 12c 特定代码使用条件编译,即 CDB 检查 - 以及或代替您的不相关版本检查。不过,在您的代码中,它似乎确实与数据库版本有关。
  • @Pha3drus - 要我扩展示例并澄清一下吗?
猜你喜欢
  • 2019-11-20
  • 1970-01-01
  • 2012-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-04
  • 2013-02-10
相关资源
最近更新 更多