保存 PL/SQL 异常并稍后引发?
Saving a PL/SQL exception and raising it later?
我有一个 PL/SQL 过程(在 Oracle 12c 数据库中)试图插入一些数据。如果失败,它应该检查 table 以查看它是否可以在那里找到一些信息来帮助解决问题。如果它找到信息,一切都很好,如果没有,它应该重新引发错误。
这是我的代码:
BEGIN
-- Try to insert some data.
INSERT INTO table VALUES x;
EXCEPTION
WHEN OTHERS THEN
BEGIN
-- Check a table to fins some info to help solve the problem.
-- If we find a row here, we can fix it.
-- If not, we should reraise the error.
SELECT * INTO y FROM table WHERE a = b;
-- Do some more stuff here to fix the problem.
EXCEPTION
WHEN NO_DATA_FOUND THEN
-- We could not find anything in the table,
-- so we could not handle the situation.
-- Reraise the error.
RAISE;
END;
END;
这里的问题是 RAISE;
语句引发了最新的异常,即 SELECT
语句抛出的 NO_DATA_FOUND
。来自 INSERT
的原始异常在堆栈中更靠下,但不在顶部。
我能否以某种方式 "save" 来自 INSERT
的错误并重新引发它?或者我可以 运行 一个 SELECT INTO
如果什么都没发现就不会抛出错误吗?我的目标是重新引发原始的 INSERT
异常,而没有任何 NO_DATA_FOUND
异常的痕迹。
编辑:查看关于为什么这不是重复的评论。
将 raise
语句从块中拉出以尝试解决问题。如果您需要在修复失败时重新提出条件,请在内部异常处理程序中设置一个标志,并且仅在该标志为真时执行 raise
。
作为代码:
DECLARE
b_reraise BOOLEAN := FALSE;
BEGIN
-- Try to insert some data.
INSERT INTO table VALUES x;
EXCEPTION
WHEN OTHERS THEN
BEGIN
-- Check a table to fins some info to help solve the problem.
-- If we find a row here, we can fix it.
-- If not, we should reraise the error.
SELECT * INTO y FROM table WHERE a = b;
-- Do some more stuff here to fix the problem.
EXCEPTION
WHEN NO_DATA_FOUND THEN
-- We could not find anything in the table,
-- so we could not handle the situation.
-- Reraise the error.
b_reraise := TRUE;
END;
IF b_reraise THEN
RAISE;
END IF;
END;
可能是这样的:
DECLARE
l_sqlerrm VARCHAR2(4000);
l_sqlerrc NUMBER;
l_exc EXCEPTION;
BEGIN
-- some code with errors
EXCEPTION
WHEN OTHERS THEN
l_sqlerrm := SQLERRM;
l_sqlerrc := SQLCODE;
-- loggin
INSERT INTO my_log (code, text) VALUES (l_sqlerrc, l_sqlerrm);
COMMIT;
-- some your code "Check a table to fins some info to help solve the problem"
-- some code to SELECT code INTO l_sqlerrc FROM my_log
PRAGMA exception_init(l_exc, l_sqlerrc);
RAISE l_exc;
END;
我有一个 PL/SQL 过程(在 Oracle 12c 数据库中)试图插入一些数据。如果失败,它应该检查 table 以查看它是否可以在那里找到一些信息来帮助解决问题。如果它找到信息,一切都很好,如果没有,它应该重新引发错误。
这是我的代码:
BEGIN
-- Try to insert some data.
INSERT INTO table VALUES x;
EXCEPTION
WHEN OTHERS THEN
BEGIN
-- Check a table to fins some info to help solve the problem.
-- If we find a row here, we can fix it.
-- If not, we should reraise the error.
SELECT * INTO y FROM table WHERE a = b;
-- Do some more stuff here to fix the problem.
EXCEPTION
WHEN NO_DATA_FOUND THEN
-- We could not find anything in the table,
-- so we could not handle the situation.
-- Reraise the error.
RAISE;
END;
END;
这里的问题是 RAISE;
语句引发了最新的异常,即 SELECT
语句抛出的 NO_DATA_FOUND
。来自 INSERT
的原始异常在堆栈中更靠下,但不在顶部。
我能否以某种方式 "save" 来自 INSERT
的错误并重新引发它?或者我可以 运行 一个 SELECT INTO
如果什么都没发现就不会抛出错误吗?我的目标是重新引发原始的 INSERT
异常,而没有任何 NO_DATA_FOUND
异常的痕迹。
编辑:查看关于为什么这不是重复的评论。
将 raise
语句从块中拉出以尝试解决问题。如果您需要在修复失败时重新提出条件,请在内部异常处理程序中设置一个标志,并且仅在该标志为真时执行 raise
。
作为代码:
DECLARE
b_reraise BOOLEAN := FALSE;
BEGIN
-- Try to insert some data.
INSERT INTO table VALUES x;
EXCEPTION
WHEN OTHERS THEN
BEGIN
-- Check a table to fins some info to help solve the problem.
-- If we find a row here, we can fix it.
-- If not, we should reraise the error.
SELECT * INTO y FROM table WHERE a = b;
-- Do some more stuff here to fix the problem.
EXCEPTION
WHEN NO_DATA_FOUND THEN
-- We could not find anything in the table,
-- so we could not handle the situation.
-- Reraise the error.
b_reraise := TRUE;
END;
IF b_reraise THEN
RAISE;
END IF;
END;
可能是这样的:
DECLARE
l_sqlerrm VARCHAR2(4000);
l_sqlerrc NUMBER;
l_exc EXCEPTION;
BEGIN
-- some code with errors
EXCEPTION
WHEN OTHERS THEN
l_sqlerrm := SQLERRM;
l_sqlerrc := SQLCODE;
-- loggin
INSERT INTO my_log (code, text) VALUES (l_sqlerrc, l_sqlerrm);
COMMIT;
-- some your code "Check a table to fins some info to help solve the problem"
-- some code to SELECT code INTO l_sqlerrc FROM my_log
PRAGMA exception_init(l_exc, l_sqlerrc);
RAISE l_exc;
END;