【问题标题】:Accessing an inner error code when running sql using execute immediate使用立即执行运行 sql 时访问内部错误代码
【发布时间】:2020-02-11 00:58:21
【问题描述】:

我正在从脚本运行下面的 PL/SQL 块。如您所见,它添加了一个列,并且应该捕获任何异常——其中,将被抛出该列的异常已经存在。

现在如果我运行这个并且列已经存在,我会得到一个错误:

错误代码:-1735

错误消息:ORA-01735:ALTER TABLE 选项无效

这一切都很好,但是如果我改为运行内部 SQL;那是 execute immediate 自己后面的 SQL,我收到了这条消息,更准确:

ORA-01430: 正在添加的列已存在于表中

第一个错误的错误代码为 -1735,我可以使用下面代码中注释掉的 when-clause 来捕获;如果它没有被注释掉,结果将是:

发生了一些其他错误

无法捕捉到 -1430 异常,尽管这似乎是异常的根本原因。

所以我的问题是:在这种情况下有没有办法访问这个“内部”异常?(在这种情况下这甚至是一个有效的术语吗?)换句话说,可以这样修改吗?为了提供更具体的错误信息?

DECLARE
    column_exists exception;
    pragma exception_init (column_exists , -1430);

    general_error exception;
    pragma exception_init (general_error , -1735);
BEGIN
    execute immediate 'ALTER TABLE my_table 
        ADD (some_column VARCHAR2(10 CHAR));';
EXCEPTION 
    -- I expected / wanted this to catch my error in order
    -- to let me output a more specific message:
    WHEN column_exists THEN    
        DBMS_OUTPUT.PUT_LINE('The column or index already exists');

 -- Note: Commented out, but would otherwise catch the general error.
 -- (I tested it here just to confirm that I can catch exceptions this way)
 --   WHEN general_error THEN    
 --       DBMS_OUTPUT.PUT_LINE('Some other error occurred');

 -- General catch: Generates the first message quoted above:
    WHEN OTHERS THEN    
        DBMS_OUTPUT.PUT_LINE('Error code: ' || SQLCODE);
        DBMS_OUTPUT.PUT_LINE('Error message: ' || SQLERRM);
END;
/

【问题讨论】:

  • 删除'..... VARCHAR2(10 CHAR));'中的;,然后重试。
  • 您也可以查看SELECT * FROM USER_TAB_COLS WHERE table_name = 'MY_TABLE';查看是否已添加列。

标签: sql oracle exception plsql dynamic-sql


【解决方案1】:

这是我稍微修改你的代码后得到的:

在第 9 行,有一个分号应该被删除,因为EXECUTE IMMEDIATE 不允许这样做,这里:

ADD (some_column VARCHAR2(10 CHAR));';
                                   ^
                                   |
                            remove it

示例表:

SQL> CREATE TABLE test
  2  AS
  3     SELECT * FROM dept;

Table created.

您的代码:

SQL> DECLARE
  2     column_exists  EXCEPTION;
  3     PRAGMA EXCEPTION_INIT (column_exists, -1430);
  4
  5     general_error  EXCEPTION;
  6     PRAGMA EXCEPTION_INIT (general_error, -1735);
  7  BEGIN
  8     EXECUTE IMMEDIATE 'ALTER TABLE test
  9          ADD (loc VARCHAR2(10 CHAR))';   --> remove ; here
 10  EXCEPTION
 11     -- I expected / wanted this to catch my error in order
 12     -- to let me output a more specific message:
 13     WHEN column_exists
 14     THEN
 15        DBMS_OUTPUT.PUT_LINE ('The column or index already exists');
 16     -- Note: Commented out, but would otherwise catch the general error.
 17     -- (I tested it here just to confirm that I can catch exceptions this way)
 18     --   WHEN general_error THEN
 19     --       DBMS_OUTPUT.PUT_LINE('Some other error occurred');
 20
 21     -- General catch: Generates the first message quoted above:
 22     WHEN OTHERS
 23     THEN
 24        DBMS_OUTPUT.PUT_LINE ('Error code: ' || SQLCODE);
 25        DBMS_OUTPUT.PUT_LINE ('Error message: ' || SQLERRM);
 26  END;
 27  /
The column or index already exists

PL/SQL procedure successfully completed.

SQL>

现在,我不确定是否是多余的分号。如有必要,将其删除并重新表述问题。

【讨论】:

  • 谢谢,看来这实际上是个错误。我无法检测到它,因为它自己运行 SQL(包括分号)工作正常。感谢您的意见!
猜你喜欢
  • 2016-11-26
  • 2019-08-25
  • 1970-01-01
  • 2023-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-08
  • 1970-01-01
相关资源
最近更新 更多