sql – 我应该在Oracle Update语句中使用Too Many Rows Error作为我的例外条款吗?

我有一系列需要在Oracle包中使用的更新语句.这种情况很少见,但可能会出现偶然且不可避免的用户错误,导致其中一个更新语句抛出“单行子查询返回一行或多行”错误.

我一直在研究oracle PL / SQl的异常处理,我对如何以及使用什么来捕获这个异常有点困惑,因此包不会崩溃.

我知道预先构建的“Too Many Rows”异常条款存在,但我读到的所有内容似乎都说它用于不正确的插入语句.

我可以将此作为我的例外吗?或者我是否需要构建自己的异常子句.我以前从来没有自己建造一个,只是粗略地想知道在哪里放置所需的一切.

以下代码基本上是如何在此特定过程中设置更新
但为了简洁起见,我只是使用一个简单的例子来说明它的外观.

INSERT INTO TempTable... --(Initial insert statement)

UPDATE TempTable t SET t.Row_one = (SELECT (Statement_One))
WHERE T.Row_One is NULL

UPDATE TempTable t SET t.Row_one = (SELECT (Statement_Two))
WHERE T.Row_One is NULL

UPDATE TempTable t SET t.Row_one = (SELECT (Statement_Three))
WHERE T.Row_One is NULL

-- Does the exception clause start here?
EXCEPTION
    WHEN TOO_MANY_ROWS THEN
(What do I tell the Procedure to do here, what am I able to tell it to do?)

--end of updates that need the exception handling

-- more insert statements into other tables based on data from the preceding Temp Table

END;

这会工作还是我需要构建自定义异常?

提前致谢.

首先,TOO_MANY_ROWS异常不会捕获select语句返回多行的情况.当您发出返回多行的SELECT .. INTO语句时,TOO_MANY_ROWS异常用于ORA-01422.您在案例中遇到的异常是ORA-01427,单行子查询返回多行.

如果要在过程中处理此特定错误,请使用EXCEPTION_INIT pragma将异常名称与错误相关联:

too_many_values EXCEPTION;
PRAGMA EXCEPTION_INIT(too_many_values, -1427);

然后,您可以在异常处理程序中引用此名称:

EXCEPTION
    WHEN TOO_MANY_VALUES THEN
       {perform your handler here}

你在处理程序中放置的内容取决于你的程序.很多时候,您需要向调用者返回某种错误代码/消息:

PROCEDURE my_proc(p_one VARCHAR2, p_err OUT VARCHAR2) IS
    too_many_values EXCEPTION;
    PRAGMA EXCEPTION_INIT(too_many_values, -1427);
BEGIN
...
EXCEPTION
   WHEN TOO_MANY_VALUES THEN
      p_err := 'More than one value available to assign in the update';
      RAISE;  -- re-raise the exception for the caller

   WHEN OTHERS THEN
      p_err := SQLERRM;  -- return the oracle message for the unexpected error
      RAISE;
END;

另一种方法是跳过特定的异常处理程序并在WHEN OTHERS处理程序中返回通用的oracle消息:

EXCEPTION
  WHEN OTHERS THEN
    p_err := SQLERRM;
END;

第一种方法的优点是,当流程的输出直接反馈给用户时,您可以自定义消息以使最终用户更友好.后一种方法的优点是涉及的编码较少.错误处理是任何应用程序的一个重要且经常受到限制的方面.

Oracle的文档是here.

编辑:

如果这是一个包,并且您希望避免通过一系列过程调用传递一长串错误变量,则可以使用包范围声明错误变量,在遇到错误时设置它,并再次升级错误.

PACKAGE BODY my_pkg is
  g_err  VARCHAR2(256);

PROCEDURE procx(... , p_err OUT VARCHAR2) IS...
  ...
  proc_y(p1);
EXCEPTION
  WHEN OTHERS THEN
    p_err := NVL(g_err, SQLERRM);
END;

PROCEDURE proc_y(p1 VARCHAR2) IS
...
proc_z(p2);

END;

PROCEDURE proc_z(p2 VARCHAR2) IS
  too_many_values EXCEPTION;
  PRAGMA EXCEPTION_INIT(too_many_values, -1427);
BEGIN
  ....
EXCEPTION
   WHEN TOO_MANY_VALUES THEN
      g_err := 'More than one value available to assign in the update';
      RAISE;  -- re-raise the exception for the caller
END;

当在proc_z中引发异常时,它会被处理然后再次引发.它通过proc_y传播回来(没有处理程序),然后在proc_x中返回给用户.未在全局g_err中设置的错误获取通用Oracle错误消息.这避免了必须在整个包中传递初始错误参数.

本站公众号
   欢迎关注本站公众号,获取更多程序园信息
开发小院