保存 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;