Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle 返回事务的成功/失败和错误消息?_Oracle_Plsql_Oracle11g - Fatal编程技术网

Oracle 返回事务的成功/失败和错误消息?

Oracle 返回事务的成功/失败和错误消息?,oracle,plsql,oracle11g,Oracle,Plsql,Oracle11g,我需要将更新和插入包装到一个事务中,该事务将从外部web应用程序调用。当调用它时,我试图返回一个基本的成功/失败状态,如果失败,还会显示一条错误消息 我想做的事情如下,但它给了我以下错误: 此SELECT语句中应包含INTO子句 “SQLCODE”:无效标识符 PL/SQL代码中的任何Select语句都需要INTO子句,从游标调用或在游标内调用的语句除外。在您的情况下,您不需要调用任何Select语句,只需将静态字符串值('TRUE','FALSE')或独立于SQL的伪列(如sqlcode或sq

我需要将更新和插入包装到一个事务中,该事务将从外部web应用程序调用。当调用它时,我试图返回一个基本的成功/失败状态,如果失败,还会显示一条错误消息

我想做的事情如下,但它给了我以下错误:

此SELECT语句中应包含INTO子句

“SQLCODE”:无效标识符


PL/SQL代码中的任何Select语句都需要INTO子句,从游标调用或在游标内调用的语句除外。在您的情况下,您不需要调用任何Select语句,只需将静态字符串值('TRUE','FALSE')或独立于SQL的伪列(如
sqlcode
sqlerrm
)分配给已定义的变量即可

>,考虑使用:

DECLARE 
    STATUS  VARCHAR2(128) := 'TRUE';  
    MESSAGE VARCHAR2(128);
BEGIN
    UPDATE MYTABLE
    SET COL1 = 400
    WHERE USERNAME = 'bigtunacan' AND pk = 12345;

    INSERT INTO MYTABLE (username, col1, col2)
            VALUES('bigtunacan', 400, 'foo');

   -- SELECT 'TRUE' AS STATUS, '' AS MSG FROM MYTABLE WHERE ROWNUM = 1;
   -- completely remove this above row, STATUS is already initialized as TRUE
    COMMIT;
EXCEPTION
  WHEN OTHERS THEN
    ROLLBACK;
    STATUS := 'FALSE'; 
    RAISE_APPLICATION_ERROR(-20333,'Caution : An error was encountered - 
                                  '||SQLCODE||' -ERROR- '||SQLERRM);

END;

理想情况下,提交/回滚不应包含在被调用的过程中。用自己的话说:

我希望PLSQL不支持提交/回滚。我坚信事务控制必须在调用程序级别的最顶层完成

您应该考虑将匿名块转换为一个过程,并在调用程序的代码中定义事务控制。

CREATE OR REPLACE procedure yourprocedure 
(      p_status  OUT VARCHAR2,
       p_message OUT VARCHAR2
       ) AS

BEGIN
  UPDATE mytable
    SET
     col1 = 400
      WHERE username = 'bigtunacan' AND pk = 12345;

INSERT INTO MYTABLE (username, col1, col2)
            VALUES('bigtunacan', 400, 'foo');

     p_status  := 'TRUE' ; 
     p_message := NULL;

EXCEPTION
    WHEN OTHERS THEN
     p_status  := 'FALSE' ; 
     p_message := SQLERRM ;
END;
/
调用(可能是另一个块、过程或应用层)


唯一的例外是,如果它被定义为一个过程(主要用于日志记录目的),您应该在该过程中进行提交。

关于这个相当不言自明的错误消息,有很多问题。但是为什么不让调用方看到异常(并决定是提交还是回滚),而不是尝试捕获和处理异常呢?(为什么成功和失败都有‘真’?)两者都有‘真’是一个错误,因为我正在输入一个较短的伪造的实际过程示例来说明我正在尝试做什么。问题是,当运行这组指令时,我希望确保它始终作为事务运行,以维护数据完整性,而不是将其留在调用方手中。同时,调用方需要知道成功或失败。您也可以在回滚后重新引发异常(即ad
raise;
)。然后调用者仍然会在出错时看到异常,在成功时什么也看不到…?而且
sqlcode
已经包含在
sqlerrm
中,所以将两者连接起来没有意义。@AlexPoole谢谢。我采用了您在回滚后重新引发异常的方法。
CREATE OR REPLACE procedure yourprocedure 
(      p_status  OUT VARCHAR2,
       p_message OUT VARCHAR2
       ) AS

BEGIN
  UPDATE mytable
    SET
     col1 = 400
      WHERE username = 'bigtunacan' AND pk = 12345;

INSERT INTO MYTABLE (username, col1, col2)
            VALUES('bigtunacan', 400, 'foo');

     p_status  := 'TRUE' ; 
     p_message := NULL;

EXCEPTION
    WHEN OTHERS THEN
     p_status  := 'FALSE' ; 
     p_message := SQLERRM ;
END;
/
DECLARE
     l_status    VARCHAR2(20);
     l_message   VARCHAR2(400);
BEGIN
     yourprocedure(l_status,l_message);

     IF
          l_status = 'TRUE'
     THEN
          COMMIT;
     ELSE
          ROLLBACK;
     END IF;
END;
/