programing

PL/SQL의 null 연관 배열에 대한 이 검사가 실패하는 이유는 무엇입니까?

muds 2023. 8. 9. 21:07
반응형

PL/SQL의 null 연관 배열에 대한 이 검사가 실패하는 이유는 무엇입니까?

테이블 열의 행 유형으로 작성된 연관 배열이 있습니다.

예를 들어, 다음과 같습니다(표 이름은 다르지만 구조는 같습니다).

테이블의 DDL입니다.

CREATE TABLE employees
  (
     id     NUMBER,
     name   VARCHAR2(240),
     salary NUMBER
  ); 

제 절차는 다음과 같습니다.

DECLARE
    TYPE table_of_emp
      IS TABLE OF employees%ROWTYPE INDEX BY BINARY_INTEGER;
    emp TABLE_OF_EMP;
BEGIN
    IF emp IS NULL THEN
      dbms_output.Put_line('Null associative array');
    ELSE
      dbms_output.Put_line('Not null');
    END IF;
END; 

로 인해 "Null 연상 배열"이 인쇄되어야 한다고 생각합니다.하지만, 그if조건이 실패하고 실행이 다른 부분으로 이동합니다.

이제 제가 이걸 넣으면,for수집 값을 인쇄하는 루프

DECLARE
    TYPE table_of_emp
      IS TABLE OF employees%ROWTYPE INDEX BY BINARY_INTEGER;
    emp TABLE_OF_EMP;
BEGIN
    IF emp IS NULL THEN
      dbms_output.Put_line('Null associative array');
    ELSE
      dbms_output.Put_line('Not null');

      FOR i IN emp.first..emp.last LOOP
          dbms_output.Put_line('Emp name: '
                               || Emp(i).name);
      END LOOP;
    END IF;
END; 

그러면 프로그램 유닛이 루프 라인에 대해 를 참조하여 예외를 발생시킵니다.

ORA-06502: PL/SQL: 숫자 또는 값 오류

제가 추측하기에 그것은 null 연상 배열 때문입니다.null 연관 배열 때문에 오류가 발생한 것입니까?

그럼 왜 첫 번째 검사가 실패하는 겁니까?내가 뭘 잘못하고 있는 거지?

데이터베이스 서버는 Oracle 11ge EE(버전 11.2.0.3.0 64비트)입니다.

이로 인해 "Null 연상 배열"이 인쇄되어야 한다고 생각합니다.이 가정은 연관 배열에 대해 잘못된 것입니다.선언할 때 존재하지만 비어 있습니다.다른 유형의 PL/SQL 컬렉션에 대해서는 다음과 같습니다.

초기화할 때까지 중첩된 테이블 또는 배열은 원자적으로 null이며, 컬렉션 자체는 해당 요소가 아닌 null입니다.중첩 테이블 또는 배열을 초기화하려면 집합 유형과 이름이 같은 시스템 정의 함수인 생성자를 사용합니다.이 함수는 전달된 요소에서 컬렉션을 구성합니다.

각 배열 및 중첩 테이블 변수에 대한 생성자를 명시적으로 호출해야 합니다. 번째 컬렉션인 연관 배열은 생성자를 사용하지 않습니다.생성자 호출은 함수 호출이 허용되는 모든 위치에서 허용됩니다.컬렉션 초기화 및 참조

비교:

SQL> declare
  2      type varchar2_100_aa is table of varchar2(100) index by binary_integer;
  3      test varchar2_100_aa;
  4  begin
  5      test(1) := 'Hello';
  6      dbms_output.put_line(test(1));
  7  end;
  8  /
Hello

PL/SQL procedure successfully completed.

SQL> declare
  2      type varchar2_100_va is varray(100) of varchar2(100);
  3      test varchar2_100_va;
  4  begin
  5      test(1) := 'Hello';
  6      dbms_output.put_line(test(1));
  7  end;
  8  /
declare
*
ERROR at line 1:
ORA-06531: Reference to uninitialized collection
ORA-06512: at line 5

변수 배열이 올바르게 수행됨:

SQL> declare
  2      type varchar2_100_va is varray(10) of varchar2(100);
  3      test varchar2_100_va;
  4  begin
  5      test := varchar2_100_va(); -- not needed on associative array
  6      test.extend; -- not needed on associative array
  7      test(1) := 'Hello';
  8      dbms_output.put_line(test(1));
  9  end;
 10  /
Hello

PL/SQL procedure successfully completed.

연관 배열이 비어 있기 때문입니다.first그리고.lastnull이므로 두 번째 예제의 결과는 다음과 같습니다.ORA-06502: PL/SQL: Numeric or value error:

SQL> declare
  2      type varchar2_100_aa is table of varchar2(100) index by binary_integer;
  3      test varchar2_100_aa;
  4  begin
  5      dbms_output.put_line(test.count);
  6      dbms_output.put_line(coalesce(to_char(test.first), 'NULL'));
  7      dbms_output.put_line(coalesce(to_char(test.last), 'NULL'));
  8      test(1) := 'Hello';
  9      dbms_output.new_line;
 10      dbms_output.put_line(test.count);
 11      dbms_output.put_line(coalesce(to_char(test.first), 'NULL'));
 12      dbms_output.put_line(coalesce(to_char(test.last), 'NULL'));
 13  end;
 14  /
0
NULL
NULL

1
1
1

PL/SQL procedure successfully completed.

편집 연관 배열은 희소할 수도 있습니다.사이의 숫자를 반복합니다.first그리고.last희소한 컬렉션에 대해 예외를 발생시킵니다.대신 사용first그리고 그렇게 함: (Last그리고.prev반대 방향으로 루프합니다.)

SQL> declare
  2      type varchar2_100_aa is table of varchar2(100) index by binary_integer;
  3      test varchar2_100_aa;
  4      i binary_integer;
  5  begin
  6      test(1) := 'Hello';
  7      test(100) := 'Good bye';
  8      dbms_output.put_line(test.count);
  9      dbms_output.put_line(coalesce(to_char(test.first), 'NULL'));
 10      dbms_output.put_line(coalesce(to_char(test.last), 'NULL'));
 11      dbms_output.new_line;
 12  --
 13      i := test.first;
 14      while (i is not null) loop
 15          dbms_output.put_line(to_char(i, '999')  || ' - ' || test(i));
 16          i := test.next(i);
 17      end loop;
 18  end;
 19  /
2
1
100

   1 - Hello
 100 - Good bye

PL/SQL procedure successfully completed.

첫 번째 점검이 실패한 이유에 대해서는 답변하지 않겠습니다.저는 그런 일을 할 생각을 해본 적이 없는데 오류를 일으키지 않는다는 것에 상당히 놀랐습니다.

루프에서 예외가 발생하는 이유는 언급했듯이 인덱스가emp.first존재하지 않습니다.

이해야 합니다. null의 존재를 확인해야 .당신은 그것을 사용할 수 있습니다..exists(i)구문:

if not emp.exists(emp.first) then
   dbms_output.put_line('Nothing in here.');
end if;

언급URL : https://stackoverflow.com/questions/12411991/why-is-this-check-for-null-associative-array-in-pl-sql-failing

반응형