본문 바로가기

Database/PLSQL

019 - [Oracle PL/SQL] Collections - Nested tables

<샘플코드에서 사용한 데이터는 HR 스키마이고, 오라클 설치시 생성할 수 있는 기본 스키마 입니다>

 

  • Nested tables

• No index in nested table ( unlike index by table )
• It is valid data type in SQL ( unlike index by table, only used in PL/SQL )
• Initialization required/초기화 필수
• Extend required/값을 추가할 경우, extend 필수
• Can be stored in DB

 

 

declare
type t_locations is table of varchar2(100);
# index is hidden in the memory

loc t_locations;

begin

loc:=t_locations('USA','UK','JORDAN');

dbms_output.put_line(loc(1) );
dbms_output.put_line(loc(2) );
dbms_output.put_line(loc(3) );

end;
-----------------
USA
UK
JORDAN

 

 

 

# for문으로 테이블 접근하는 방법.
declare
type t_locations is table of varchar2(100);

loc t_locations;

begin

loc:=t_locations('USA','UK','JORDAN');
  for i in loc.first..loc.last
  loop
  dbms_output.put_line(loc(i) );
  end loop;

end;
-----------------
USA
UK
JORDAN

 

 

 

  • extend 가 필요한 경우는 인덱스를 숨김처리한 경우와 초기화를 동시에 한 경우에 해당 된다(이제 보니 멍청한 설명임, nested tables 개념을 잊어버려서 이렇게 설명함).
# 초기화 이후 값을 추가하려면 extend 명령어를 이용해야 한다.
declare
    type t_locations is table of varchar2(100);
    loc t_locations;
begin
    loc:=t_locations('USA','UK','JORDAN');
    loc.extend;
    loc(4):='Lebanon';
    dbms_output.put_line(loc(1) );
    dbms_output.put_line(loc(2) );
    dbms_output.put_line(loc(3) );
    dbms_output.put_line(loc(4) );
end;
---------------------
USA
UK
JORDAN
Lebanon


# 인덱스 타입을 정의하면 "binary_integer/pls_integer" 오류가 발생한다. 둘다 발생함.
declare
--    type t_locations is table of varchar2(100)  index by binary_integer;
    type t_locations is table of varchar2(100)  index by pls_integer;
    loc t_locations;
begin
    loc:=t_locations('USA','UK','JORDAN');
    loc.extend;
    loc(4):='Lebanon';
    dbms_output.put_line(loc(1) );
    dbms_output.put_line(loc(2) );
    dbms_output.put_line(loc(3) );
    dbms_output.put_line(loc(4) );
end;
---------------------
Error report -
ORA-06550: line 5, column 22:
PLS-00681: named association syntax is required
ORA-06550: line 5, column 5:
PL/SQL: Statement ignored
ORA-06550: line 6, column 5:
PLS-00306: wrong number or types of arguments in call to 'EXTEND'
ORA-06550: line 6, column 5:
PL/SQL: Statement ignored
06550. 00000 -  "line %s, column %s:\n%s"
*Cause:    Usually a PL/SQL compilation error.


# 인덱스 선언 & no 초기화.
declare
    type t_locations is table of varchar2(100) index by binary_integer;
    loc t_locations:=t_locations();
begin
--    loc:=t_locations('USA','UK','JORDAN');
--    loc.extend;
    loc(1):='USA';
    loc(2):='UK';
    loc(3):='JORDAN';
    loc(4):='Lebanon';
    dbms_output.put_line(loc(1) );
    dbms_output.put_line(loc(2) );
    dbms_output.put_line(loc(3) );
    dbms_output.put_line(loc(4) );
end;
--------------------
USA
UK
JORDAN
Lebanon



# nested table은 초기화 필수, extend 필수 이므로 아래처럼 조건을 계속 바꾸면서 테스트하면 바보.
declare
    type t_locations is table of varchar2(100);
    loc t_locations:=t_locations();-- nested table, Initialization required
begin
--    loc:=t_locations('USA','UK','JORDAN');
    loc.extend;
    loc(1):='USA';
    loc.extend;
    loc(2):='UK';
    loc.extend;
    loc(3):='JORDAN';
    loc.extend;
    loc(4):='Lebanon';
    dbms_output.put_line(loc(1) );
    dbms_output.put_line(loc(2) );
    dbms_output.put_line(loc(3) );
    dbms_output.put_line(loc(4) );
end;
--------------------
USA
UK
JORDAN
Lebanon

 

 

 

# index에 값이 없는 경우, 해당 인덱스에 접근하면 바로 종료 된다.

declare
    type t_locations is table of varchar2(100);
    loc t_locations;
begin
    loc:=t_locations('jordan','uae','Syria');
    loc.delete(2);
    loc(2):='Iraq';
    -- 정상적인 샘플 코드

    dbms_output.put_line('---------');
    dbms_output.put_line(loc(1) );
    dbms_output.put_line(loc(2) );
    dbms_output.put_line(loc(3) );
    dbms_output.put_line('---------');
end;
---------
jordan
Iraq
Syria
---------


declare
    type t_locations is table of varchar2(100);
    loc t_locations;
begin
    loc:=t_locations('jordan','uae','Syria');
    loc.delete(2);
    --loc(2):='Iraq';
    --2번에 값이 없으면 그 이후는 출력이 되지 않는다. 아래의 출력 결과를 확인.

    dbms_output.put_line('---------');
    dbms_output.put_line(loc(1) );
    dbms_output.put_line(loc(2) );
    dbms_output.put_line(loc(3) );
    dbms_output.put_line('---------');
end;
---------
jordan

 

 

 

# 샘플 코드

drop table x_customer;
drop type t_tel;


create or replace type t_tel as table of number;
--Type T_TEL compiled


--아래의 2 명령어를 한번에 실행해야 생성된다.
create table x_customer
( cust_id number,
  cust_name varchar2(20),
  tel t_tel
)
nested table tel store as t_tel_tbl;
--Table X_CUSTOMER created.


insert into x_customer (cust_id,cust_name,tel)
values (1,'khaled',t_tel(050121,0501245,0589877));
--1 row inserted.


select * from x_customer;

/*
   CUST_ID CUST_NAME            TEL                           
---------- -------------------- ------------------------------
         1 khaled               T_TEL(50121, 501245, 589877) 
*/