Tuesday, September 16, 2008

DB2 LOOP INSERT

ปกติถ้าเราจะ insert ข้อมูลลง database โดยเอาข้อมูลจาก
table อื่นมาก็มักจะใช้ insert ... select ... แบบนี้
เพราะเขียนสั้น ง่ายดี แต่ใน DB2 นั้นบางทีถ้าข้อมูลที่
select ขึ้นมานั้นมีปริมาณมากๆ อาจะไม่หมูอย่างทีคิดก็เป็นได้
เพราะการใช้ insert....select..... นั้นการทำงานดังรูป


ref: http://publib.boulder.ibm.com/infocenter/dzichelp/v2r2/topic/com.ibm.db2tools.oe.doc.ug/dvnhlpwithin.gif

วันนี้ผมเลยขอแนะนำการ fetch cursor เพือ่ insert ข้อมูล
ลงไปใน table แทน เคยลองมาแล้วครับเร็วมากครับ
ลองดูตัวอย่างเลยครับ

สร้างตารางสำหรับเก็บข้อมูลก่อน
CREATE TABLE TB_DATA(
DATA1 VARCHAR(128) NOT NULL,
DATA2 VARCHAR(128)
)

ต่อมาก็เริ่มดู procedure กันเลยครับ

CREATE PROCEDURE SP_FETCH_INTSERT()
LANGUAGE SQL
BEGIN
--Author: Mr.Fuangwith S.
DECLARE v_not_found CHARACTER(1) DEFAULT '1';
DECLARE v_tabname VARCHAR(128);
DECLARE v_type CHARACTER(1);
DECLARE c1 CURSOR FOR
SELECT
TABNAME,
TYPE
FROM
SYSCAT.TABLES
FOR READ ONLY;

--v_not_found = 1 after fetch cursor pass last record
DECLARE EXIT HANDLER FOR NOT FOUND
SET v_not_found = '1';


OPEN c1;
SET v_not_found = '0';
FETCH_LOOP:
LOOP
FETCH c1 INTO v_tabname,v_type;
--exit loop when finish
IF v_not_found = '1' THEN
LEAVE FETCH_LOOP;
END IF;

INSERT INTO TB_DATA(
DATA1,
DATA2
)VALUES(
v_tabname,
v_type
);
END LOOP FETCH_LOOP;
SET v_not_found = '1';
CLOSE c1;

END
GO
CALL SP_FETCH_INTSERT()

จาก procedure ด้านบนอธิบายได้ดังนั้นครับ
ขั้นแรกก็ประกาศ cursor C1 ขึ้นมาเพื่อใช้ในการ fetch
TabName และ Type จาก syscat.tables
จากนั้นทำการวนลูป โดย scope ของ loop คือ
fetch_loop ครับ ในขณะที่วนลูปก็เอาค่าขึ้นมา
เก็บไว้ที่ตัวแปร v_tabname, v_type แล้ว
ก็ inset ของ table TB_DATA ครับ
เมื่อ fetch ข้อมูลออกมาจาก cursor จนหมด
มันก็จะเกิด exception NOT FOUND ขึ้นน่ะครับ
ค่าตัวแปร v_not_found ก็จะกลายเป็น 1
แล้วมันก็จะออกจาก loop ในที่สุดครับ

No comments: