สมมติว่า แอ็พพลิเคชันของคุณจำเป็นต้องจัดการกับคำสั่ง
SELECT แบบ dynamic เมื่อค่าหนึ่งเปลี่ยนเป็นอีกค่าหนึ่งสำหรับใช้ต่อไป
คำสั่งนี้สามารถอ่านได้จากจอแสดงผล ซึ่งถูกส่งผ่านจากแอ็พพลิเคชันอื่น
หรือถูกสร้างขึ้นจากแอ็พพลิเคชันของคุณแบบ dynamic
พูดได้อีกอย่างว่า, คุณไม่ทราบแน่ชัดว่า
คำสั่งนี้จะส่งค่าอะไรคืนกลับมาในทุกครั้ง.
แอ็พพลิเคชันจำเป็นต้องจัดการกับจำนวนที่แตกต่างกันออกไปของคอลัมน์ผลลัพธ์ที่ไม่ทราบชนิดข้อมูลที่แน่นอนก่อนล่วงหน้า
ยกตัวอย่างเช่น, คำสั่งต่อไปนี้จำเป็นจะต้องถูกประมวลผล:
SELECT WORKDEPT,
PHONENO
FROM CORPDATA.EMPLOYEE
WHERE LASTNAME =
'PARKER'
หมายเหตุ: คำสั่ง SELECT นี้ไม่มี
INTO clause. คำสั่ง SELECT แบบ
dynamic จะต้องไม่ มี INTO clause, ถึงแม้ว่าจะส่งค่าคืนมาเพียงแถวเดียว.
คำสั่งจะถูกกำหนดค่าให้กับตัวแปรโฮสต์.
ตัวแปรโฮสต์, ในกรณีนี้มีชื่อว่า DSTRING, จะถูกทำการประมวลผลโดยใช้คำสั่ง
PREPARE ตามที่ได้แสดงไว้ดังนี้:
EXEC SQL
PREPARE S1 FROM :DSTRING;
ขั้นถัดไป, คุณจำเป็นจะต้องหาค่าจำนวนของคอลัมน์ผลลัพธ์และชนิดของข้อมูล.
หากต้องการทำสิ่งนี้, คุณจำเป็นต้องจัดสรรจำนวน entry ขนาดใหญ่สุดสำหรับ
SQL descriptor ที่คุณคิดว่าคุณต้องการ. สมมติว่า
มีคอลัมน์ไม่เกิน 20 คอลัมน์ถูกเรียกใช้โดยคำสั่ง SELECT เดียว.
EXEC SQL
ALLOCATE DESCRIPTOR 'mydescr' WITH MAX 20;
ถึงตอนนี้ descriptor จะถูกจัดสรร,
คำสั่ง DESCRIBE สามารถเรียกใช้เพื่อรับข้อมูลคอลัมน์.
EXEC SQL
DESCRIBE S1 USING DESCRIPTOR 'mydescr';
เมื่อคำสั่ง DESCRIBE ถูกรัน,
SQL จะใส่ค่าที่ได้เตรียมข้อมูลเกี่ยวกับรายการที่เลือกของคำสั่งเข้าไปใน
SQL descriptor area ซึ่งถูกนิยามโดย 'mydescr'.
ถ้า DESCRIBE กำหนดว่า
มี entry ไม่เพียงพอที่จะถูกจัดสรรใน descriptor,
SQLCODE +239 จะถูกเรียกใช้. ส่วนหนึ่งของการวินิจฉัยนี้,
การแทนที่ค่าข้อความที่สองจะบ่งชี้ถึงจำนวนของ entry ที่ต้องการ.
ตัวอย่างโค้ดต่อไปนี้แสดงวิธีที่เงื่อนไขนี้สามารถตรวจพบ และแสดง descriptor
ที่ถูกจัดสรรด้วยขนาดที่ใหญ่กว่า.
/* Determine the returned SQLCODE from the DESCRIBE
statement */
EXEC SQL
GET DIAGNOSTICS
CONDITION 1: returned_sqlcode = DB2_RETURNED_SQLCODE;
if returned_sqlcode = 239 then do;
/* Get the second token for the SQLCODE that indicated
not enough
entries were allocated */
EXEC SQL
GET DIAGNOSTICS
CONDITION 1: token = DB2_ORDINAL_TOKEN_2;
/* Move the token
variable from a character host variable into an integer host variable */
EXEC SQL
SET :var1 =
:token;
/* Deallocate the
descriptor that is too small */
EXEC SQL
DEALLOCATE
DESCRIPTOR 'mydescr';
/* Allocate the new
descriptor to be the size indicated by the retrieved token */
EXEC SQL
ALLOCATE
DESCRIPTOR 'mydescr' WITH MAX :var1;
/* Perform the
describe with the larger descriptor */
EXEC SQL
DESCRIBE s1 USING
DESCRIPTOR 'mydescr';
end;
ถึงตอนนี้ descriptor จะมีข้อมูล
เกี่ยวกับคำสั่ง SELECT และคุณพร้อมที่จะดึงผลลัพธืของคำสั่ง SELECT
ออกมา. สำหรับ SQL แบบ dynamic, คำสั่ง
SELECT INTO จะไม่อนุญาตให้ใช้. คุณต้องใช้เคอร์เซอร์.
EXEC SQL
DECLARE C1 CURSOR
FOR S1;
คุณจะสังเกตว่า ชื่อคำสั่งที่ถูกจัดเตรียมจะถูกใช้ในการประกาศเคอร์เซอร์แทนการทำคำสั่ง
SELECT ให้สมบูรณ์. ถึงตอนนี้
คุณสามารถวนซ้ำแถวที่เลือก, ประมวลผลแถวเหล่านั้นตามที่คุณอ่านได้.
ตัวอย่างโค้ดต่อไปนี้แสดงถึงวิธีการทำสิ่งนี้.
EXEC SQL
OPEN C1;
EXEC SQL
FETCH C1 USING SQL
DESCRIPTOR 'mydescr';
do while not at end of data;
/* process current
data returned (see below for discussion
of doing this) */
/* then read the next row */
EXEC SQL
FETCH C1 USING SQL
DESCRIPTOR 'mydescr';
end;
EXEC SQL
CLOSE C1;
เคอร์เซอร์ถูกเปิด. แถวที่เป็นผลลัพธ์จากคำสั่ง
SELECT จะถูกส่งคืนมาครั้งละหนึ่งแถวโดยใช้คำสั่ง FETCH.
ในคำสั่ง FETCH, จะไม่มีรายชื่อของตัวแปรโฮสต์อยู่.
แทนที่จะเป็นเช่นนั้น, คำสั่ง FETCH จะบอกให้
SQL ส่งคืนผลลัพธ์เข้าไปใน descriptor area.
หลังจากประมวลผล FETCH แล้ว,
คุณสามารถใช้คำสั่ง GET DESCRIPTOR เพื่ออ่านค่าเหล่านั้น.
อันดับแรก, คุณต้องอ่านค่าส่วนหัวที่บ่งชี้ถึงจำนวน descriptor
entry ที่ถูกใช้.
EXEC SQL
GET DESCRIPTOR
'mydescr' :count = COUNT;
หลังจากนั้น
คุณสามารถอ่านข้อมูลเกี่ยวกับ descriptor entry แต่ละตัว.
หลังจากที่คุณกำหนดชนิดข้อมูลของคอลัมน์ผลลัพธ์แล้ว, คุณสามารถทำให้
GET DESCRIPTOR อื่นส่งคืนค่าที่เป็นจริง.
หากต้องการรับค่าของตัวบ่งชี้, ให้ระบุไอเท็ม INDICATOR. ถ้าค่าของไอเท็ม
INDICATOR เป็นลบ, ค่าของไอเท็ม
DATA จะไม่ถูกนิยาม. จนกว่า FETCH อื่นจะถูกทำ,
ไอเท็ม descriptor จะยังคงรักษาค่าเหล่านั้นไว้.
do i = 1 to count;
GET DESCRIPTOR
'mydescr' VALUE :i /* set entry number
to get */
:type = TYPE,
/* get the data type */
:length = LENGTH,
/* length value */
:result_ind = INDICATOR;
if result_ind >= 0
then
if type =
character
GET DESCRIPTOR
'mydescr' VALUE :i
:char_result = DATA; /* read
data into character field */
else
if type = integer
GET DESCRIPTOR
'mydescr' VALUE :i
:int_result = DATA; /* read
data into integer field */
else
/* continue
checking and processing for all data types that might be returned */
end;
มีไอเท็ม descriptor อื่นๆ
หลายไอเท็มที่คุณอาจต้องการตรวจสอบ เพื่อกำหนดวิธีการจัดการกับข้อมูลผลลัพธ์. PRECISION,
SCALE, DB2_CCSID, และ DATETIME_INTERVAL_CODE อยู่ระหว่างกัน.
ตัวแปรโฮสต์ที่มีการอ่านค่า DATA เข้าไปในตัวแปรต้องมีชนิดข้อมูลเดียวกัน
และ CCSID ต้องเป็นข้อมูลที่อ่านได้.
ถ้าชนิดข้อมูลมีความยาวผันแปร, ตัวแปรโฮสต์จะถูกประกาศความยาวได้ยาวกว่าข้อมูลจริง.
สำหรับชนิดข้อมูลอื่นๆ ทั้งหมด, ความยาวต้องตรงกัน.
NAME, DB2_SYSTEM_COLUMN_NAME, และ
DB2_LABEL จะถูกใช้เพื่อรับค่าชื่อที่สัมพันธ์กันสำหรับคอลัมน์ผลลัพธ์.
โปรดดู GET DESCRIPTOR สำหรับข้อมูลเพิ่มเติมเกี่ยวกับไอเท็มที่ถูกส่งคืนสำหรับคำสั่ง
GET DESCRIPTOR และสำหรับ definition ของค่า
TYPE