programing

%NOTFOUND가 페치 후 null을 반환할 수 있습니까?

stoneblock 2023. 10. 16. 21:28

%NOTFOUND가 페치 후 null을 반환할 수 있습니까?

질문은 매우 흥미로운 점을 제기했습니다. Oracle 문서에 다음과 같은 작업이 가능한지에 대한 모순이 있는 것 같습니다.%NOTFOUND페치 후에 무효가 되는 것.그런가요?

11g 설명서에서 인용하기

참고: 예제 6-16에서 FETCH가 행을 가져오지 않으면 c1%NOTFOUND는 항상 NULL이고 루프는 종료되지 않습니다.무한 루프를 방지하려면 이 EX를 사용합니다.대신 IT 문: c1%가 발견되지 않거나(c1%가 발견되지 않으면 NULL) 종료;

이 문서는 다음과 같이 말하는 것과 직접적으로 모순되는 것으로 보이는데, 이는 페치 후에 다음을 의미합니다.%NOTFOUND null일 수 없습니다.

%NOTFOUND(%FOUND의 논리적 반대)가 반환합니다.
명시적 커서가 열린 후 첫 번째 가져오기 전에 NULL
명시적 커서에서 가장 최근에 가져온 가져오기에서 행이 반환된 경우 FALSE
그렇지 않으면 TRUE

10g 문서에는 이 동작이 표시되기 위해 페치가 성공적으로 실행되지 않을 수 있다는 경고가 있으므로 이와 유사한 경고가 있습니다.

첫 번째 페치 전에 %NOTFOUND가 NULL로 평가됩니다. FETCH가 성공적으로 실행되지 않으면 EXIT WHEN 조건이 참이 아니며 루프가 종료되지 않습니다.안전을 위해 다음 EX를 사용할 수 있습니다.대신 IT 진술:

c1% not found 또는 c1% not found가 Null일 때 종료;

어떤 상황에서 "실패" 또는 "실패"를 가져올 수 있는지 여부%NOTFOUND가져오기가 실행된 후 null을 반환하시겠습니까?

가져오기가 실패할 수 있는 상황을 찾을 수 있습니다.

declare
  i integer;
  cursor c is
    select 1 / 0 from dual;
begin
  open c;

  begin
    fetch c
      into i;
  exception
    when others then
      dbms_output.put_line('ex');
  end;

  if c%notfound is null then
    dbms_output.put_line('null');
  elsif c%notfound then
    dbms_output.put_line('true');
  else
    dbms_output.put_line('false');
  end if;
  close c;

end;

그러나 이것은 당신의 질문을 더 강하게 만들 뿐입니다. 그것은 10g도 11g도 아닌 null로 평가될 것이기 때문입니다.

제 생각에 당신을 곤경에 빠뜨리는 부분은 다음과 같습니다.

FETCH가 성공적으로 실행되지 않으면 EXIT WHEN 조건이 참이 아니며 루프가 종료되지 않습니다.

과거 어딘가에 다음과 같은 코드 예시가 있었을 것입니다.

LOOP
  FETCH c1 INTO name;
  EXIT WHEN c1%NOTFOUND;
  -- Do stuff
END LOOP;

이 코드 덩어리가 주어지면 문장이 true로 울립니다.가져오기가 실행되지 않으면(실패) %NOTFOUND는 null이 됩니다.EXIT WHEN조건은 TRUE로 평가되지 않습니다(null은 false로 평가됨).그러면 정말로 그 고리는 영원히 계속될 것입니다.

이는 쉽게 테스트할 수 있는 상황입니다.

SET SERVEROUT ON;

DECLARE
  -- this cursor returns a single row
  CURSOR c1 IS
    SELECT 1 FROM dual WHERE rownum = 1;

  -- this cursor returns no rows
  CURSOR c2 IS
    SELECT 1 FROM dual WHERE 1=0;

  v1 number;
BEGIN
  OPEN c1;
  FETCH c1 INTO v1; -- this returns a record
  FETCH c1 INTO v1; -- this does not return a record
  IF c1%NOTFOUND THEN
    dbms_output.put_line('c1%NOTFOUND: TRUE');
  ELSIF c1%NOTFOUND IS NULL THEN
    dbms_output.put_line('c1%NOTFOUND: NULL');
  ELSE
    dbms_output.put_line('c1%NOTFOUND: FALSE');
  END IF;
  CLOSE c1;

  OPEN c2;
  FETCH c2 INTO v1; -- this does not return a record
  IF c2%NOTFOUND THEN
    dbms_output.put_line('c2%NOTFOUND: TRUE');
  ELSIF c2%NOTFOUND IS NULL THEN
    dbms_output.put_line('c2%NOTFOUND: NULL');
  ELSE
    dbms_output.put_line('c2%NOTFOUND: FALSE');
  END IF;
  CLOSE c2;
END;
/

Oracle APEX 4.1의 스크립트 출력은 다음과 같습니다(APEX가 Oracle 11gR2를 실행하고 있다고 생각하지만 스크립트를 어떤 버전에서도 쉽게 실행할 수 있습니다).

c1%NOTFOUND: TRUE
c2%NOTFOUND: TRUE

,%NOTFOUND페치가 실행된 후에는 NULL이 되지 않습니다.은 과 11g합니다에 및 있는 과 일치합니다.%NOTFOUND기여하다. 가 절대 않는다는 는 이전 에서 가져온 .루프가 절대 빠져나가지 않는다는 내용의 노트는 이전 버전의 예제에서 가져온 것이어야 합니다.메모에 불과하기 때문에 처음 설명을 믿고 메모를 무시해도 무방하다고 생각합니다.

언급URL : https://stackoverflow.com/questions/11273185/can-notfound-return-null-after-a-fetch