返回交易成功/失败和错误信息?

时间:2018-12-11 14:41:57

标签: oracle plsql oracle11g

我需要进行更新,然后将其插入到将从外部Web应用程序调用的事务中。尝试调用它时,我会尝试恢复基本的成功/失败状态,如果失败,则会显示一条错误消息。

我想做的事情类似于以下内容,但是它给了我以下错误:

  

此SELECT语句中应包含INTO子句

     

“ SQLCODE”:无效的标识符

DECLARE STATUS VARCHAR2(128); 
    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;

    COMMIT;
EXCEPTION
    WHEN OTHERS THEN
            ROLLBACK;
            SELECT 'FALSE' AS STATUS, SQLCODE || SQLERRM AS MSG FROM MYTABLE WHERE ROWNUM = 1;
END;

2 个答案:

答案 0 :(得分:1)

PL / SQL代码中的任何Select语句都需要一个INTO子句,但从游标中或游标中调用的子句除外。就您而言,您无需调用任何Select语句,只需将静态字符串值('TRUE','FALSE')或独立于SQL的伪列(例如sqlcodesqlerrm)分配给已定义的变量。

因此,请考虑使用:

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;

答案 1 :(得分:0)

理想情况下,不应将Commit / Rollback包括在被调用过程中。用Tom Kyte's自己的话:

  

我希望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;
/

调用(可能是另一个块,过程或应用程序层)

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;
/

唯一的例外是将其定义为Autonomous过程(主要用于记录目的),您应该在该过程中进行提交。