【问题标题】:How to ignore compilation error in Oracle pl/sql when script is executed by certain types of user某些类型的用户执行脚本时如何忽略 Oracle pl/sql 中的编译错误
【发布时间】:2021-03-09 10:40:05
【问题描述】:

我想要一种简单的方法,在我的团队成员登录 SQLPlus 时自动确认架构属于哪个客户,以避免出错。

我将 glogin.sql 配置如下,当以架构所有者身份登录时效果很好:

set echo off
set serveroutput on
set linesize 200

Declare
   sysDesc varchar2(255);
BEGIN

  if USER like '%SCHEMAOWNER%' then
    select DESCRIPTION into sysDesc from SCHEMA_INFO;
  else
    sysDesc := '(DBA User)';
  end if; 

  dbms_output.put_line('*******************************************************************');
  dbms_output.put_line('WARNING - THIS IS A CUSTOMER SYSTEM!!!');
  dbms_output.put_line('*******************************************************************' || chr(13) || chr(10));
  dbms_output.put_line('- Description:   ' || SysDesc);
  dbms_output.put_line('- User:  ' || USER);
  dbms_output.put_line('- Database:      ' || sys_context('USERENV','DB_NAME') || chr(13) || chr(10));
  dbms_output.put_line('*******************************************************************');

END;
/

但是,有时我们需要以 DBA 用户身份登录。 DBA 用户看不到 SCHEMA_INFO 表,因此用户收到此错误:

ERROR at line 9:
ORA-06550: line 9, column 43:
PL/SQL: ORA-00942: table or view does not exist
ORA-06550: line 9, column 5:
PL/SQL: SQL Statement ignored

我试图添加一个异常处理程序,但后来意识到这是一个编译错误,所以这没有用。我也尝试使用立即执行,但找不到使用 select 语句输出的方法。

有谁知道我可以如何忽略编译错误或根据用户类型运行不同的脚本/块?

【问题讨论】:

    标签: oracle plsql sqlplus


    【解决方案1】:

    为不存在的表异常创建自定义异常,如果发生则捕获它:

    set echo off
    set serveroutput on
    set linesize 200
    
    Declare
       sysDesc varchar2(255);
    BEGIN
    
      if USER like '%SCHEMAOWNER%' then
        DECLARE
          table_or_view_does_not_exist EXCEPTION;
          PRAGMA EXCEPTION_INIT( table_or_view_does_not_exist, -942 );
        BEGIN
          EXECUTE IMMEDIATE 'select DESCRIPTION from SCHEMA_INFO' into sysDesc;
        EXCEPTION
          WHEN table_or_view_does_not_exist THEN
            -- You should validate that the user is a DBA here.
            sysDesc := '(DBA User)';
        END;
      else
        sysDesc := '(DBA User)';
      end if; 
    
      dbms_output.put_line('*******************************************************************');
      dbms_output.put_line('WARNING - THIS IS A CUSTOMER SYSTEM!!!');
      dbms_output.put_line('*******************************************************************' || chr(13) || chr(10));
      dbms_output.put_line('- Description:   ' || SysDesc);
      dbms_output.put_line('- User:  ' || USER);
      dbms_output.put_line('- Database:      ' || sys_context('USERENV','DB_NAME') || chr(13) || chr(10));
      dbms_output.put_line('*******************************************************************');
    
    END;
    /
    

    【讨论】:

    • 感谢您的尝试。不幸的是,我收到了ERROR at line 21: ORA-06550: line 21, column 45: PL/SQL: ORA-00942: table or view does not exist ORA-06550: line 21, column 7: PL/SQL: SQL Statement ignored
    • @Andy 更新为使用EXECUTE IMMEDIATE,因此在编译时不会检查表的存在,因此会在运行时引发异常。
    猜你喜欢
    • 2011-09-06
    • 1970-01-01
    • 2012-02-09
    • 2012-08-20
    • 1970-01-01
    • 2015-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多