sourcecode

이 Oracle ORA-01403을 처리하는 올바른 방법은 무엇입니까? 데이터를 찾을 수 없음 예외?

codebag 2023. 10. 10. 20:17
반응형

이 Oracle ORA-01403을 처리하는 올바른 방법은 무엇입니까? 데이터를 찾을 수 없음 예외?

제가 대기열처럼 취급하는 DB 테이블이 있습니다.나는 그것에서 하나의 물건을 가져오려고 합니다.SELECT..를 제외하고는 작동합니다.INTO 실패(대기열에 하나의 항목만 있고 두 명의 사용자가 다른 컴퓨터에서 항목을 가져오려고 하면 하나만 성공합니다.)

그러면 익숙한 ORA-01403: 데이터를 찾을 수 없음 예외로 이어집니다.이 경우에 NULL 레코드를 반환하도록 SP를 변경하려고 했습니다. 쿼리에서 얻을 수 있는 것과 같은 종류의 결과로 레코드를 찾을 수 없습니다. 그러나 아무 소용이 없었습니다.제가 여기서 뭔가 잘못하고 있습니다.

PROCEDURE sp_GetNextEmailFromQueue (pAgentId IN NUMBER, pRecs OUT recordSet)
  IS
  EMAIL_ID INTEGER;
  BEGIN

     SELECT id INTO EMAIL_ID FROM
           (SELECT id, is_replied_to, is_being_worked, date_received 
           FROM SSQ_EMAILS
           WHERE is_replied_to = 0 AND is_being_worked =0
           ORDER BY date_received ASC)
     WHERE rownum = 1;


    UPDATE SSQ_EMAILS x 
             SET x.is_being_worked = 1,
                 x.agent_id = pAgentId,
                 x.work_started_date = SYSDATE
             WHERE x.id = EMAIL_ID;

    OPEN pRecs FOR
      SELECT x.id,
             x.message_id,
             x.to_email,
             x.from_email,
             x.subject,
             x.message,
             x.date_received,
             x.href_link,
             x.is_being_worked,
             x.work_started_date,
             x.is_replied_to
        FROM SSQ_EMAILS x
        WHERE x.id = EMAIL_ID;

        EXCEPTION
          WHEN no_data_found 
            THEN 
              OPEN pRecs FOR
              SELECT NULL
              FROM SSQ_EMAILS;

  END;

예외 핸들러를 코드 조각 주위에 배치할 것입니다. 실제로 오류가 발생하는 경우email_idNULL입니다.UPDATE어떤 행도 업데이트하지 않습니다.SELECT행을 반환하지 않습니다.

PROCEDURE sp_GetNextEmailFromQueue (pAgentId IN NUMBER, pRecs OUT recordSet)
  IS
  EMAIL_ID INTEGER;
  BEGIN
    BEGIN
      SELECT id 
        INTO EMAIL_ID 
        FROM (SELECT id, is_replied_to, is_being_worked, date_received 
                FROM SSQ_EMAILS
               WHERE is_replied_to = 0 AND is_being_worked =0
               ORDER BY date_received ASC)
       WHERE rownum = 1;
    EXCEPTION
      WHEN no_data_found 
      THEN
        email_id := null;
    END;

    UPDATE SSQ_EMAILS x 
             SET x.is_being_worked = 1,
                 x.agent_id = pAgentId,
                 x.work_started_date = SYSDATE
             WHERE x.id = EMAIL_ID;

    OPEN pRecs FOR
      SELECT x.id,
             x.message_id,
             x.to_email,
             x.from_email,
             x.subject,
             x.message,
             x.date_received,
             x.href_link,
             x.is_being_worked,
             x.work_started_date,
             x.is_replied_to
        FROM SSQ_EMAILS x
        WHERE x.id = EMAIL_ID;
  END;

그러나 이 코드는 두 명의 다른 발신자가 동일한 행에서 작업하는 것을 방해하지는 않습니다.두 세션이 동시에 이 절차를 호출하는 경우 두 세션 모두 동일한 행을 선택할 수 있습니다.그걸 막으려면,SELECT선택한 행을 잠글 필요가 있을 것입니다.FOR UPDATE

이 경우에는 아무것도 할 수 없습니다.

exception
  when no_data_found then
    null;
end;

null in을 반환합니다.pRecs그렇죠?

편집

두 번째 접근 방식:

cursor c_mail is
  SELECT id  
    FROM
       (SELECT id, is_replied_to, is_being_worked, date_received 
          FROM SSQ_EMAILS
         WHERE is_replied_to = 0 AND is_being_worked =0
         ORDER BY date_received ASC)
   WHERE rownum = 1;
....
open c_mail;
fetch c_mail into email_id; -- no_data_found not happens
close c_mail;

예외 처리를 피하면 어떨까요?

/* returns X */
SELECT DUMMY FROM DUAL WHERE 1 = 1;

/* no data found */
SELECT DUMMY FROM DUAL WHERE 1 = 0;

/* returns NULL */
SELECT MIN(DUMMY) FROM DUAL WHERE 1 = 0;

select null from ssq_emails표에 기록이 없을 경우에도 1403을 얻을 수 있습니다.예외 처리기에서 어떤 작업을 수행할지 확실하지 않습니다. 호출자가 어떻게 처리할지 확실하지 않습니다.pRecs허전하기는 하지만.

이 작업을 통해 해결:

EXCEPTION
   WHEN no_data_found THEN 
      OPEN pRecs FOR
      SELECT NULL
      FROM SSQ_EMAILS  s
      WHERE s.id IS NULL;

RefCursor를 열어야 하기 때문에 작동합니다.빈 결과가 필요합니다. ID는 PK이고 null이 될 수 없기 때문에 이를 보장하는 안전한 방법인 것 같습니다.

언급URL : https://stackoverflow.com/questions/9104153/what-is-the-correct-way-to-deal-with-this-oracle-ora-01403-no-data-found-except

반응형