Хранимая процедура не возвращает ожидаемое пользовательское сообщение об исключении - PullRequest
0 голосов
/ 05 января 2019

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

CREATE OR replace PROCEDURE user_details(v_ownerid    IN NUMBER, 
                                             v_branchcode IN NVARCHAR2, 
                                             v_login      IN NVARCHAR2, 
                                             cv_1         OUT SYS_REFCURSOR) 
IS 
  result_out1   SYS_REFCURSOR; 
  v_territoryid NUMBER(10); 
  v_user        NUMBER(10); 
  CURSOR cc IS 
    SELECT Z.username AS USERNAME, 
           Z.loginid  AS LOGINID, 
           Z.userid   AS CRMUSERID 
    FROM   userterritory U 
           inner join teammembers T 
                   ON U.ownerid = T.ownerid 
                      AND U.userid = T.memberid 
           inner join az_user Z 
                   ON Z.appownerid = T.ownerid 
                      AND Z.userid = T.memberid; 
  TYPE tbl_join 
    IS TABLE OF cc%ROWTYPE; 
  l_table       TBL_JOIN; 
BEGIN 
    SELECT regionid 
    INTO   v_territoryid 
    FROM   regions 
    WHERE  ownerid = v_ownerid 
           AND categorytype = 3 
           AND code = v_branchcode; 

    SELECT userid 
    INTO   v_user 
    FROM   az_user 
    WHERE  appownerid = v_ownerid 
           AND loginid = v_login; 

    OPEN result_out1 FOR 
      SELECT Z.username AS USERNAME, 
             Z.loginid  AS LOGINID, 
             Z.userid   AS CRMUSERID 
      FROM   userterritory U 
             inner join teammembers T 
                     ON U.ownerid = T.ownerid 
                        AND U.userid = T.memberid 
             inner join az_user Z 
                     ON Z.appownerid = T.ownerid 
                        AND Z.userid = T.memberid 
      WHERE  Z.appownerid = v_ownerid 
             AND T.reportsto = v_user 
             AND U.territoryid = v_territoryid; --using whereClause;      
    FETCH result_out1 bulk collect INTO l_table; 

--    FETCH result_out1 bulk collect INTO l_table; 

    dbms_output.Put_line('Count ' 
                         || l_table.count); 

    IF l_table.count > 0 THEN 
      OPEN cv_1 FOR 
        SELECT Z.username AS USERNAME, 
               Z.loginid  AS LOGINID, 
               Z.userid   AS CRMUSERID 
        FROM   userterritory U 
               inner join teammembers T 
                       ON U.ownerid = T.ownerid 
                          AND U.userid = T.memberid 
               inner join az_user Z 
                       ON Z.appownerid = T.ownerid 
                          AND Z.userid = T.memberid 
        WHERE  Z.appownerid = v_ownerid 
               AND T.reportsto = v_user 
               AND U.territoryid = v_territoryid; 
    ELSE 
      Raise_application_error(-20001, 'Data Not Found.'); 
    END IF; 
END; 

Эта хранимая процедура вызывает исключение, если данные отсутствуют. Но вместо того, чтобы возвращать пользовательское сообщение об исключении, оно возвращает системное исключение:

ORA-01403: данные не найдены

Я что-то здесь не так делаю? Есть ли какие-либо изменения, которые необходимо сделать, чтобы вернуть сообщение об исключительной ситуации, т. Е. «Данные не найдены»? Я собираюсь изменить это сообщение. Ранее я использовал ниже SP, но он не возвращал никаких сообщений об ошибках в случае 0 записей, потому что я сделал изменения, как указано в хранимой процедуре:

CREATE OR replace PROCEDURE user_details(v_ownerid    IN NUMBER, 
                                             v_branchcode IN NVARCHAR2, 
                                             v_login      IN NVARCHAR2, 
                                             cv_1         OUT SYS_REFCURSOR) 
AS 
  v_territoryid NUMBER(10); 
  v_user        NUMBER(10); 
BEGIN 
    SELECT regionid 
    INTO   v_territoryid 
    FROM   regions 
    WHERE  ownerid = v_ownerid 
           AND categorytype = 3 
           AND code = v_branchcode; 

    SELECT userid 
    INTO   v_user 
    FROM   az_user 
    WHERE  appownerid = v_ownerid 
           AND loginid = v_login; 

    OPEN cv_1 FOR 
      SELECT Z.username AS USERNAME, 
             Z.loginid  AS LOGINID, 
             Z.userid   AS CRMUSERID 
      FROM   userterritory U 
             inner join teammembers T 
                     ON U.ownerid = T.ownerid 
                        AND U.userid = T.memberid 
             inner join az_user Z 
                     ON Z.appownerid = T.ownerid 
                        AND Z.userid = T.memberid 
      WHERE  Z.appownerid = v_ownerid 
             AND T.reportsto = v_user 
             AND U.territoryid = v_territoryid; 
END; 

1 Ответ

0 голосов
/ 05 января 2019

ORA-01403: no data found вызывается из любого из двух операторов выбора перед вами BULK COLLECT из CURSOR.

Кроме того, ваш код, кажется, содержит несколько избыточных конструкций, делающих его излишне сложным . Например, единственная цель CURSOR cc состоит в том, чтобы определить табличную переменную этого типа, и использование BULK COLLECT не требуется, если вы хотите просто проверить, существуют ли записи перед открытием курсора.

Вы можете переписать это так.

CREATE OR replace PROCEDURE user_details (v_ownerid    IN NUMBER, 
                                          v_branchcode IN NVARCHAR2, 
                                          v_login      IN NVARCHAR2, 
                                          cv_1         OUT SYS_REFCURSOR) 
IS 
  v_territoryid NUMBER(10); 
  v_user        NUMBER(10); 
  l_count       INT; 
BEGIN 
    SELECT regionid 
    INTO   v_territoryid 
    FROM   regions 
    WHERE  ownerid = v_ownerid 
           AND categorytype = 3 
           AND code = v_branchcode; 

    SELECT userid 
    INTO   v_user 
    FROM   az_user 
    WHERE  appownerid = v_ownerid 
           AND loginid = v_login; 

    SELECT CASE 
             WHEN EXISTS (SELECT 1  --check if a row exists.
                          FROM   userterritory u 
                                 INNER JOIN teammembers t 
                                         ON u.ownerid = t.ownerid 
                                            AND u.userid = t.memberid 
                                 INNER JOIN az_user z 
                                         ON z.appownerid = t.ownerid 
                                            AND z.userid = t.memberid 
                          WHERE  z.appownerid = v_ownerid 
                                 AND t.reportsto = v_user 
                                 AND u.territoryid = v_territoryid) THEN 1 
             ELSE 0 
           END 
    INTO   l_count 
    FROM   dual; 

    IF l_count = 1 THEN 
      OPEN cv_1 FOR 
        SELECT z.username AS username, 
               z.loginid  AS loginid, 
               z.userid   AS crmuserid 
        FROM   userterritory u 
               INNER JOIN teammembers t 
                       ON u.ownerid = t.ownerid 
                          AND u.userid = t.memberid 
               INNER JOIN az_user z 
                       ON z.appownerid = t.ownerid 
                          AND z.userid = t.memberid 
        WHERE  z.appownerid = v_ownerid 
               AND t.reportsto = v_user 
               AND u.territoryid = v_territoryid; 
    ELSE 
      raise_application_error(-20001, 'Data Not Found.'); 
    END IF; 
EXCEPTION 
  WHEN no_data_found THEN 
             raise_application_error(-20001, 'regionid or userid not Found.'); 
        -- Handling the exception  
        --for errors from first 2 selects 
END; 
/ 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...