복붙노트

[SQL] ORA-22905 - SELECT 문을 사용하여 테이블 유형을 쿼리 할 때

SQL

ORA-22905 - SELECT 문을 사용하여 테이블 유형을 쿼리 할 때

 DECLARE
 TYPE record_AB IS RECORD
   (
      AA              VARCHAR2 (16 BYTE),
      BB    VARCHAR2 (16 BYTE)
   );

  TYPE type_tab_AB IS TABLE OF record_AB
                        INDEX BY BINARY_INTEGER;

  tab_AB   type_tab_AB;

  BEGIN
   SELECT *
    BULK COLLECT INTO tab_AB FROM...
    ..
    SELECT * FROM TABLE (tab_AB) ;

내가 얻을 "ORA-22905 : 수 비 중첩 테이블 항목에서 액세스 할 행"은 TABLE 문에서 SELECT를 가져옵니다.

그것은 PL SQL 내에서 테이블 형식을 조회도 가능합니까?

해결법

  1. ==============================

    1.그것은 PL / SQL 쿼리 테이블 유형에 가능하지만, 단지 중첩 된 테이블과 그 유형의 스키마 수준, PL / SQL의 즉 외부에서 선언 varrays.

    그것은 PL / SQL 쿼리 테이블 유형에 가능하지만, 단지 중첩 된 테이블과 그 유형의 스키마 수준, PL / SQL의 즉 외부에서 선언 varrays.

    오류

    지원되지 않는 테이블 형식에서 쿼리하려고하는 것을 의미한다. 귀하의 유형 type_tab_AB 때문에 BINARY_INTEGER 절 BY 인덱스, 연관 배열입니다. 당신의 type_tab_AB 중첩 된 테이블 형식 만들 수있는 INDEX BY BINARY_INTEGER 절을 제거합니다. (Varrays도 여기서 일 것입니다,하지만 당신은 상부 기대하는 행의 수 행 알지 못한다면 내가 그들을를 사용하지 않는 것이 좋습니다 것이다. VARRAY 유형을 선언하면 중첩 된 테이블 유형이있는 반면, 요소의 최대 번호를 지정해야 이러한 제한이 없음).

    이 변경을 한 후, 당신의 코드는 여전히 작동하지 않을 수 있습니다. 당신이 얻을 수 있습니다 다음 오류는 (그렇게하지 않으면 아래의 설명을 참조)

    당신이에 선택하는 유형이 PL / SQL 내에서 선언되어 있기 때문입니다. 당신은 CREATE TYPE에 사용 type_tab_AB 및 PL / SQL의 record_AB의 외부를 선언 할 필요가 ....

    발생할 다음 문제는 키워드 RECORD이 될 것입니다. 레코드 유형에만 PL / SQL 내에서 만들 수 있습니다, 그들은 스키마 수준에서 만들 수 없습니다. OBJECT로 변경 RECORD는이 문제를 해결합니다.

    당신이 발생합니다 마지막 문제는 t.BB의 BULK이 FROM ... INTO 문 tab_AB를 수집, 선택 t.AA 함께. 약자로,이 쿼리는 당신에게 다음과 같은 오류를 줄 것이다 :

    각 행에서이 개 항목을 선택하고 데이터를 대량 삽입에에 하나의 테이블을 제공하고 있습니다. 오라클은 확실히 당신이 당신의 record_AB 타입으로 두 항목을 물건을 할 것인지 알아낼 수 없습니다. 당신은 .... FROM INTO tab_AB를 수집 SELECT record_AB (t.AA, t.BB) BULK에 쿼리를 변경하여 비교적 쉽게이 문제를 해결할 수 있습니다

    종합적으로 이러한 변화는 문제를 해결해야한다. 다음은 몇 가지 테스트 데이터는 테이블 형식을 조회 할 수 있는지 확인과 테스트 테이블을 생성하는 전체 SQL * 플러스 스크립트는 다음과 같습니다

    CREATE TABLE some_table (AA VARCHAR2(16 BYTE), BB VARCHAR2(16 BYTE));
    
    INSERT INTO some_table (AA, BB) VALUES ('aa 1', 'bb 1');
    INSERT INTO some_table (AA, BB) VALUES ('aaaaaaaaaa 2', 'b 2');
    INSERT INTO some_table (AA, BB) VALUES ('aaaaa 3', 'bbbbbbbbbbbbbb 3');
    COMMIT;
    
    VARIABLE curs REFCURSOR;
    
    CREATE OR REPLACE TYPE record_AB AS OBJECT
       (
          AA    VARCHAR2 (16 BYTE),
          BB    VARCHAR2 (16 BYTE)
       );
    /
    
    CREATE OR REPLACE TYPE type_tab_AB IS TABLE OF record_AB;
    /
    
    DECLARE
      tab_AB   type_tab_AB;
    BEGIN
      SELECT record_AB(t.AA, t.BB)
        BULK COLLECT INTO tab_AB 
        FROM some_table t;
    
      OPEN :curs FOR SELECT * FROM TABLE (tab_AB) ;
    END;
    /
    
    PRINT :curs
    

    나는 커서로 tab_AB의 내용을 선택하는 결과를 놓고, 그 내용을 목록에 SQL * Plus를 커서 변수를 사용했습니다. 의 모든 '종류가 만든'이후 내가 얻을 출력은 내가 오라클 11g XE에서 스크립트를 실행할 때 'PL / SQL이 성공적으로 완료 절차'메시지, 같은 다음입니다 :

    AA               BB
    ---------------- ----------------
    aa 1             bb 1
    aaaaaaaaaa 2     b 2
    aaaaa 3          bbbbbbbbbbbbbb 3
    

    참고 : 단순화하기 위해, 나는 오라클 11 이상을 사용하고 질문자 가정했습니다. 오라클 (12)에서, 나는 당신이 PL / SQL에서 SQL 쿼리 발생할하지 않을 수 있도록 PLS-00642 오류에 선언 사용 유형에 사용할 수 있습니다 생각합니다. 나는 오라클 (12)를 사용하여 아직 나의 대답에 다른 변화는 또한 오라클 (12)에 대한 필요가 무엇인지 말할 수 없습니다.

  2. ==============================

    2.당신은 PL / SQL 블록 내부에 생성 된 유형을 쿼리 할 수 ​​없습니다. 당신은 SQL 프롬프트를 만들 필요가 그리고 당신은 그것을 쿼리 할 수 ​​있습니다. exmaple을 아래 참조 :

    당신은 PL / SQL 블록 내부에 생성 된 유형을 쿼리 할 수 ​​없습니다. 당신은 SQL 프롬프트를 만들 필요가 그리고 당신은 그것을 쿼리 할 수 ​​있습니다. exmaple을 아래 참조 :

    scott@ORA92> CREATE OR REPLACE TYPE emp_type AS OBJECT
      2    (id   NUMBER,
      3     name VARCHAR2(20));
      4  /
    
    Type created.
    
    scott@ORA92> CREATE OR REPLACE TYPE emp_tab AS TABLE OF emp_type;
      2  /
    
    Type created.
    
    scott@ORA92> VARIABLE g_ref REFCURSOR
    scott@ORA92> DECLARE
      2    employees emp_tab := emp_tab();
      3  BEGIN
      4    employees.EXTEND(2);
      5    employees(1) := emp_type (1, 'name1');
      6    employees(2) := emp_type (2, 'name2');
      7    OPEN :g_ref FOR
      8    SELECT * FROM TABLE (CAST (employees AS emp_tab));
      9  END;
     10  /
    
  3. from https://stackoverflow.com/questions/19208264/ora-22905-when-querying-a-table-type-with-a-select-statement by cc-by-sa and MIT license