发生错误时如何退出sqlplus

mlw*_*mos 0 oracle error-handling sqlplus

我想捕获任何可能发生的SQL错误,所以我在ksh中写了这个:

$ORACLE_HOME/bin/sqlplus -s u/p <<EOF
    WHENEVER OSERROR EXIT 68;
    WHENEVER SQLERROR EXIT SQL.SQLCODE;

    CREATE TABLE new_table
    AS (SELECT * FROM wrong_old_table);
    COMMIT;
EOF
Run Code Online (Sandbox Code Playgroud)

我为旧表输入了错误的名称以查看会发生什么。我希望只有在WHENEVER SQLERROR中询问时才具有sqlcode,但是我有这个:

 AS (SELECT * FROM wrong_old_table)
                      *
 ERROR at line 2:
 ORA-00942: table or view does not exist
Run Code Online (Sandbox Code Playgroud)

我更改了代码:

 $ORACLE_HOME/bin/sqlplus -s u/p <<EOF
    WHENEVER OSERROR EXIT 68;
    WHENEVER SQLERROR EXIT SQL.SQLCODE;

    BEGIN
       CREATE TABLE new_table
       AS (SELECT * FROM wrong_old_table);
       COMMIT;
    END;
 EOF

 sql_code=$?

 echo "code=$sql_code"
Run Code Online (Sandbox Code Playgroud)

即使有错误,代码也等于0。sql错误代码在哪里?


实际上,不使用begin ... end就可以了

Bob*_*ica 5

我不确定您在做什么,但是这种类型的代码对我来说很好用。对于第一个示例:

SQL> whenever sqlerror exit sql.sqlcode;
SQL> create table new_table as select * from wrong_old_table;
create table new_table as select * from wrong_old_table
                                        *
ERROR at line 1:
ORA-00942: table or view does not exist

$ echo $?
174
Run Code Online (Sandbox Code Playgroud)

请注意,退出代码与SQLCODE并不完全对应,因为SQLCODE始终为负,而大多数外壳程序中的退出代码限制为+0到+255;因此,您似乎以退出代码得到的是SQLCODE(+)的二进制补码的低位字节。实际上,这意味着您将获得一个非零值,该值是可预测和可重复的,但不会与SQLCODE完全匹配,并且多个SQLCODE值可能会产生相同的退出代码值。

祝你好运。

(+)如果您关心:在上面的示例中,SQLCODE为-942。以十六进制表示的是0xFFFFFC52。将此数字的所有位取反,即可得到一个补码,即0x3AD。在此值上加一个,即可得到两个的补码值,即0x3AE。它的低位字节是0xAE,在基数10中为174。对于SQLCODE值-904(给出的退出代码为136)和-6550(给出的退出代码为150),我已经重复了此操作。