Oracle PL / SQL – 使用自定义SQLERRM引发用户定义的exception
是否可以创build用户定义的exception并能够更改SQLERRM?
例如:
DECLARE ex_custom EXCEPTION; BEGIN RAISE ex_custom; EXCEPTION WHEN ex_custom THEN DBMS_OUTPUT.PUT_LINE(SQLERRM); END; /
输出是“用户定义的例外”。 有没有可能改变这个讯息?
编辑:这是一些更多的细节。
我希望这个说明我想要做的更好。
DECLARE l_table_status VARCHAR2(8); l_index_status VARCHAR2(8); l_table_name VARCHAR2(30) := 'TEST'; l_index_name VARCHAR2(30) := 'IDX_TEST'; ex_no_metadata EXCEPTION; BEGIN BEGIN SELECT STATUS INTO l_table_status FROM USER_TABLES WHERE TABLE_NAME = l_table_name; EXCEPTION WHEN NO_DATA_FOUND THEN -- raise exception here with message saying -- "Table metadata does not exist." RAISE ex_no_metadata; END; BEGIN SELECT STATUS INTO l_index_status FROM USER_INDEXES WHERE INDEX_NAME = l_index_name; EXCEPTION WHEN NO_DATA_FOUND THEN -- raise exception here with message saying -- "Index metadata does not exist." RAISE ex_no_metadata; END; EXCEPTION WHEN ex_no_metadata THEN DBMS_OUTPUT.PUT_LINE('Exception will be handled by handle_no_metadata_exception(SQLERRM) procedure here.'); DBMS_OUTPUT.PUT_LINE(SQLERRM); END; /
实际上,有几十个这样的子块。 我想知道是否有一种方法可以为每个子块创build一个用户定义的exception,但是它会给出不同的消息,而不是为每个子块创build一个单独的用户定义的exception。
在.NET中,这就像有一个像这样的自定义exception:
public class ColorException : Exception { public ColorException(string message) : base(message) { } }
然后,一个方法会有这样的事情:
if (isRed) { throw new ColorException("Red is not allowed!"); } if (isBlack) { throw new ColorException("Black is not allowed!"); } if (isBlue) { throw new ColorException("Blue is not allowed!"); }
是。 你只需要使用RAISE_APPLICATION_ERROR
函数。 如果您还想命名exception,则需要使用EXCEPTION_INIT
编译指示,以便将错误编号与指定的exception相关联。 就像是
SQL> ed Wrote file afiedt.buf 1 declare 2 ex_custom EXCEPTION; 3 PRAGMA EXCEPTION_INIT( ex_custom, -20001 ); 4 begin 5 raise_application_error( -20001, 'This is a custom error' ); 6 exception 7 when ex_custom 8 then 9 dbms_output.put_line( sqlerrm ); 10* end; SQL> / ORA-20001: This is a custom error PL/SQL procedure successfully completed.
你可以像这样使用RAISE_APPLICATION_ERROR:
DECLARE ex_custom EXCEPTION; BEGIN RAISE ex_custom; EXCEPTION WHEN ex_custom THEN RAISE_APPLICATION_ERROR(-20001,'My exception was raised'); END; /
这将引发一个exception,如下所示:
ORA-20001: My exception was raised
错误号可以是-20001和-20999之间的任何值。
我通常会忽略所有-20001
型错误代码,所以我尝试将所有的应用程序错误整合到一个很好的包中,例如:
SET SERVEROUTPUT ON CREATE OR REPLACE PACKAGE errors AS invalid_foo_err EXCEPTION; invalid_foo_num NUMBER := -20123; invalid_foo_msg VARCHAR2(32767) := 'Invalid Foo!'; PRAGMA EXCEPTION_INIT(invalid_foo_err, -20123); -- can't use var >:O illegal_bar_err EXCEPTION; illegal_bar_num NUMBER := -20156; illegal_bar_msg VARCHAR2(32767) := 'Illegal Bar!'; PRAGMA EXCEPTION_INIT(illegal_bar_err, -20156); -- can't use var >:O PROCEDURE raise_err(p_err NUMBER, p_msg VARCHAR2 DEFAULT NULL); END; / CREATE OR REPLACE PACKAGE BODY errors AS unknown_err EXCEPTION; unknown_num NUMBER := -20001; unknown_msg VARCHAR2(32767) := 'Unknown Error Specified!'; PROCEDURE raise_err(p_err NUMBER, p_msg VARCHAR2 DEFAULT NULL) AS v_msg VARCHAR2(32767); BEGIN IF p_err = unknown_num THEN v_msg := unknown_msg; ELSIF p_err = invalid_foo_num THEN v_msg := invalid_foo_msg; ELSIF p_err = illegal_bar_num THEN v_msg := illegal_bar_msg; ELSE raise_err(unknown_num, 'USR' || p_err || ': ' || p_msg); END IF; IF p_msg IS NOT NULL THEN v_msg := v_msg || ' - '||p_msg; END IF; RAISE_APPLICATION_ERROR(p_err, v_msg); END; END; /
然后调用errors.raise_err(errors.invalid_foo_num, 'optional extra text')
来使用它,就像这样:
BEGIN BEGIN errors.raise_err(errors.invalid_foo_num, 'Insufficient Foo-age!'); EXCEPTION WHEN errors.invalid_foo_err THEN dbms_output.put_line(SQLERRM); END; BEGIN errors.raise_err(errors.illegal_bar_num, 'Insufficient Bar-age!'); EXCEPTION WHEN errors.illegal_bar_err THEN dbms_output.put_line(SQLERRM); END; BEGIN errors.raise_err(-10000, 'This Doesn''t Exist!!'); EXCEPTION WHEN OTHERS THEN dbms_output.put_line(SQLERRM); END; END; /
产生这个输出:
ORA-20123: Invalid Foo! - Insufficient Foo-age! ORA-20156: Illegal Bar! - Insufficient Bar-age! ORA-20001: Unknown Error Specified! - USR-10000: This Doesn't Exist!!
declare z exception; begin if to_char(sysdate,'day')='sunday' then raise z; end if; exception when z then dbms_output.put_line('to day is sunday'); end;
create or replace PROCEDURE PROC_USER_EXP AS duplicate_exp EXCEPTION; PRAGMA EXCEPTION_INIT( duplicate_exp, -20001 ); LVCOUNT NUMBER; BEGIN SELECT COUNT(*) INTO LVCOUNT FROM JOBS WHERE JOB_TITLE='President'; IF LVCOUNT >1 THEN raise_application_error( -20001, 'Duplicate president customer excetpion' ); END IF; EXCEPTION WHEN duplicate_exp THEN DBMS_OUTPUT.PUT_LINE(sqlerrm); END PROC_USER_EXP;
- Java:作为控制stream的exception?
- 获取android.content.res.Resources $ NotFoundException:即使资源存在于android中也是exception
- 从exception对象中提取回溯信息
- 为什么Double.parseDouble(null)和Integer.parseInt(null)会抛出不同的exception?
- 多次或单次尝试抓住
- Debug.Assert与exception抛出
- 即使你抛出一个新的exception,finally块是否会运行?
- 在C#中实现自定义exception的行业标准最佳实践是什么?
- 在Java中有没有像.NET的NotImplementedException?