ネスト表を使ってみた

テーブルのカラムにテーブルが作れるらしいので試してみました。
下記の親子関係のテーブルをネスト表に書き換えてみます。

CREATE TABLE CUSTOMER
(
	ID		NUMBER NOT NULL,
	NAME	VARCHAR2(100),
	CONSTRAINT PK_CUSTOMER PRIMARY KEY (ID) USING INDEX
);
/
CREATE TABLE ADDRESS
(
	ID				NUMBER NOT NULL,
	CUSTOMER_ID		NUMBER,
	ZIP_CODE		VARCHAR2(10),
	CONSTRAINT PK_ADDRESS PRIMARY KEY (ID) USING INDEX,
	CONSTRAINT FK_ADDRESS FOREIGN KEY (CUSTOMER_ID) REFERENCES CUSTOMER (ID)
);
/

INSERT INTO CUSTOMER(ID,NAME) VALUES(1,'取引先A');
/
INSERT ALL
INTO ADDRESS(ID,CUSTOMER_ID,ZIP_CODE) VALUES (1,1,'1234567')
INTO ADDRESS(ID,CUSTOMER_ID,ZIP_CODE) VALUES (2,1,'3216543')
SELECT * FROM DUAL;
/

SELECTする

SELECT
	 C.ID AS CUSTOMER_ID
	,C.NAME
	,A.ID AS ADDRESS_ID
	,A.ZIP_CODE
FROM
	CUSTOMER C
INNER JOIN
	ADDRESS A
ON
	A.CUSTOMER_ID = C.ID;

結果

CUSTOMER_ID NAME ADDRESS_ID ZIP_CODE
1 取引先A 1 1234567
1 取引先A 2 3216543


これを、ネスト表で表現してみる。

まずADDRESSテーブルと同様のTYPEと、その作成したTYPEでTABLEのTYPEを作成

CREATE TYPE NEST_ADDRESS AS OBJECT (ZIP_CODE VARCHAR(10));
/
CREATE OR REPLACE TYPE NEST_ADDRESS_LIST AS TABLE OF NEST_ADDRESS;
/

次にCUSTOMERテーブル作成
ADDRESS_LIST カラムのTYPE をさっきつくったNEST_ADDRESS_LISTにします

CREATE TABLE NEST_CUSTOMER
(
	ID NUMBER,
	NAME VARCHAR2(100),
	ADDRESS_LIST NEST_ADDRESS_LIST
)
NESTED TABLE ADDRESS_LIST STORE AS ADDRESS_NTAB;
/

これで完成です。

次にデータをINSERTしてみます。
NEST_ADDRESS_LIST TYPE に、 NEST_ADDRESS TYPE のデータを複数いれます。

INSERT INTO NEST_CUSTOMER(ID,NAME,ADDRESS_LIST)
VALUES(1,'取引先A',
	NEST_ADDRESS_LIST(
		 NEST_ADDRESS('1234567')
		,NEST_ADDRESS('3216543')
	)
);

で、SELECTします。
TABLE(ネストカラム)で取得します。

SELECT
	 N.ID
	,N.NAME
	,A.ZIP_CODE
FROM
	 NEST_CUSTOMER N
	,TABLE(N.ADDRESS_LIST) A

結果、ちゃんとADDRESS_LIST に2レコード入ってることがわかります。

ID NAME ZIP_CODE
1 取引先A 1234567
1 取引先A 3216543


ADDRESS_LIST の データをいじりたいときはどうすれば良いのか調べて見たところ
下記のように一度レコードをサブクエリで指定してあげてから操作するようです。

INSERT

INSERT INTO TABLE(SELECT ADDRESS_LIST FROM NEST_CUSTOMER WHERE ID = 1)
VALUES(NEST_ADDRESS('987654321'));
ID NAME ZIP_CODE
1 取引先A 1234567
1 取引先A 3216543
1 取引先A 987654321

UPDATE

UPDATE TABLE (SELECT ADDRESS_LIST FROM NEST_CUSTOMER WHERE ID = 1) NC
SET VALUE(NC) = NEST_ADDRESS('111111')
WHERE NC.ZIP_CODE = '987654321';
ID NAME ZIP_CODE
1 取引先A 1234567
1 取引先A 3216543
1 取引先A 111111

DELETE

DELETE FROM TABLE(SELECT ADDRESS_LIST FROM NEST_CUSTOMER WHERE ID = 1) NC
WHERE
NC.ZIP_CODE = '111111';
ID NAME ZIP_CODE
1 取引先A 1234567
1 取引先A 3216543

ひとまず今日はここまで。。。
難しかった上にあまり使い道が思いつかないですね。