Вернуть сообщение об успехе / неудаче и об ошибке транзакции? - PullRequest
0 голосов
/ 11 декабря 2018

Мне нужно иметь обновление и вставить в транзакцию, которая будет вызываться из внешнего веб-приложения.Я пытаюсь вернуть базовый статус успеха / неудачи, когда он вызывается вместе с сообщением об ошибке, если произошел сбой.

Что я хотел бы сделать, это что-то вроде следующего, но это дает мне следующееошибки:

В этом операторе 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 голосов
/ 11 декабря 2018

Commit / Rollback не должен идеально включаться в вызываемую процедуру.От собственных слов Тома Кайта :

Я бы хотел, чтобы 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;
/

Единственное исключение, если оно определено как Автономный процедура (в основном используется для регистрации), где вы должны совершать внутри процедуры.

0 голосов
/ 11 декабря 2018

Любой оператор Select внутри кода PL / SQL нуждается в предложении 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...