Oracle เคอร์เซอร์ PL/SQL: โดยนัย, ชัดเจน, สำหรับลูปพร้อมตัวอย่าง
เคอร์เซอร์ใน PL/SQL คืออะไร?
เคอร์เซอร์เป็นตัวชี้ไปยังพื้นที่บริบทนี้ Oracle สร้างพื้นที่บริบทสำหรับการประมวลผลคำสั่ง SQL ซึ่งมีข้อมูลทั้งหมดเกี่ยวกับคำสั่ง
PL/SQL ช่วยให้โปรแกรมเมอร์ควบคุมพื้นที่บริบทผ่านเคอร์เซอร์ เคอร์เซอร์เก็บแถวที่ส่งคืนโดยคำสั่ง SQL ชุดของแถวที่เคอร์เซอร์เก็บไว้เรียกว่าชุดที่ใช้งานอยู่ เคอร์เซอร์เหล่านี้สามารถตั้งชื่อเพื่อให้สามารถอ้างอิงจากที่อื่นของโค้ดได้
เคอร์เซอร์มีสองประเภท
- เคอร์เซอร์โดยปริยาย
- เคอร์เซอร์ที่ชัดเจน
เคอร์เซอร์โดยปริยาย
เมื่อใดก็ตามที่มีการดำเนินการ DML ในฐานข้อมูล จะมีการสร้างเคอร์เซอร์โดยปริยายที่เก็บแถวที่ได้รับผลกระทบในการดำเนินการนั้นๆ เคอร์เซอร์เหล่านี้ไม่สามารถตั้งชื่อได้ ดังนั้นจึงไม่สามารถควบคุมหรืออ้างอิงจากตำแหน่งอื่นของโค้ดได้ เราสามารถอ้างอิงเคอร์เซอร์ล่าสุดได้ผ่านแอตทริบิวต์เคอร์เซอร์เท่านั้น
เคอร์เซอร์ที่ชัดเจน
โปรแกรมเมอร์สามารถสร้างพื้นที่บริบทที่มีชื่อเพื่อดำเนินการ DML เพื่อให้ควบคุมได้มากขึ้น ควรกำหนดเคอร์เซอร์ที่ชัดเจนในส่วนการประกาศของ บล็อก PL/SQLและถูกสร้างขึ้นสำหรับคำสั่ง 'SELECT' ที่จำเป็นต้องใช้ในโค้ด
ด้านล่างนี้เป็นขั้นตอนที่เกี่ยวข้องกับการทำงานกับเคอร์เซอร์ที่ชัดเจน
- ประกาศเคอร์เซอร์ การประกาศเคอร์เซอร์หมายถึงการสร้างพื้นที่บริบทที่มีชื่อสำหรับคำสั่ง 'SELECT' ที่กำหนดไว้ในส่วนการประกาศ ชื่อของพื้นที่บริบทนี้เหมือนกับชื่อเคอร์เซอร์
- กำลังเปิดเคอร์เซอร์การเปิดเคอร์เซอร์จะสั่งการ PL / SQL เพื่อจัดสรรหน่วยความจำสำหรับเคอร์เซอร์นี้ มันจะทำให้เคอร์เซอร์พร้อมที่จะดึงข้อมูล
- การดึงข้อมูลจากเคอร์เซอร์ในกระบวนการนี้ คำสั่ง 'SELECT' จะถูกดำเนินการ และแถวที่ดึงข้อมูลมาจะถูกจัดเก็บไว้ในหน่วยความจำที่จัดสรร สิ่งเหล่านี้เรียกว่าเป็นชุดที่ใช้งานอยู่ การดึงข้อมูลจากเคอร์เซอร์เป็นกิจกรรมระดับบันทึกซึ่งหมายความว่าเราสามารถเข้าถึงข้อมูลในลักษณะบันทึกต่อบันทึก แต่ละคำสั่งการดึงข้อมูลจะดึงชุดที่ใช้งานอยู่หนึ่งชุดและเก็บข้อมูลของบันทึกนั้น ๆ คำสั่งนี้เหมือนกับคำสั่ง 'SELECT' ที่ดึงข้อมูลบันทึกและกำหนดให้กับตัวแปรในส่วนคำสั่ง 'INTO' แต่จะไม่เกิดข้อยกเว้นใดๆ
- การปิดเคอร์เซอร์เมื่อดึงบันทึกทั้งหมดแล้ว เราจำเป็นต้องปิดเคอร์เซอร์เพื่อที่หน่วยความจำที่จัดสรรให้กับพื้นที่บริบทนี้จะถูกปล่อยออกมา
วากยสัมพันธ์
DECLARE CURSOR <cursor_name> IS <SELECT statement^> <cursor_variable declaration> BEGIN OPEN <cursor_name>; FETCH <cursor_name> INTO <cursor_variable>; . . CLOSE <cursor_name>; END;
- ในรูปแบบข้างต้น ส่วนการประกาศประกอบด้วยการประกาศของเคอร์เซอร์และตัวแปรเคอร์เซอร์ซึ่งข้อมูลที่ดึงมาจะถูกกำหนด
- เคอร์เซอร์ถูกสร้างขึ้นสำหรับคำสั่ง 'SELECT' ที่กำหนดไว้ในการประกาศเคอร์เซอร์
- ในส่วนของการดำเนินการ เคอร์เซอร์ที่ประกาศจะถูกเปิด ดึงข้อมูล และปิด
คุณสมบัติเคอร์เซอร์
ทั้งเคอร์เซอร์โดยปริยายและเคอร์เซอร์โดยชัดแจ้งต่างก็มีคุณลักษณะบางอย่างที่สามารถเข้าถึงได้ คุณลักษณะเหล่านี้ให้ข้อมูลเพิ่มเติมเกี่ยวกับการทำงานของเคอร์เซอร์ ด้านล่างนี้คือคุณลักษณะเคอร์เซอร์ต่างๆ และการใช้งาน
แอตทริบิวต์เคอร์เซอร์ | Descriptไอออน |
---|---|
%พบ | ส่งคืนผลลัพธ์บูลีน 'TRUE' หากการดำเนินการดึงข้อมูลล่าสุดดึงข้อมูลระเบียนสำเร็จ มิฉะนั้นจะส่งคืนค่า FALSE |
%ไม่พบ | วิธีนี้ทำงานตรงข้ามกับ %FOUND โดยจะส่งกลับค่า 'TRUE' หากการดำเนินการดึงข้อมูลครั้งล่าสุดไม่สามารถดึงข้อมูลบันทึกใดๆ ได้ |
%เปิด | จะส่งกลับผลลัพธ์บูลีน 'TRUE' ถ้าเคอร์เซอร์ที่กำหนดถูกเปิดอยู่แล้ว มิฉะนั้นจะส่งกลับ 'FALSE' |
%ROWCOUNT | มันจะส่งกลับค่าตัวเลข โดยจะให้จำนวนบันทึกจริงที่ได้รับผลกระทบจากกิจกรรม DML |
ตัวอย่างเคอร์เซอร์ที่ชัดเจน:
ในตัวอย่างนี้ เราจะดูวิธีการประกาศ เปิด ดึงข้อมูล และปิดเคอร์เซอร์ที่ชัดเจน
เราจะฉายชื่อพนักงานทั้งหมดจากตาราง emp โดยใช้เคอร์เซอร์ นอกจากนี้เรายังใช้แอตทริบิวต์เคอร์เซอร์เพื่อตั้งค่าการวนซ้ำเพื่อดึงข้อมูลบันทึกทั้งหมดจากเคอร์เซอร์
DECLARE CURSOR guru99_det IS SELECT emp_name FROM emp; lv_emp_name emp.emp_name%type; BEGIN OPEN guru99_det; LOOP FETCH guru99_det INTO lv_emp_name; IF guru99_det%NOTFOUND THEN EXIT; END IF; Dbms_output.put_line(‘Employee Fetched:‘||lv_emp_name); END LOOP; Dbms_output.put_line(‘Total rows fetched is‘||guru99_det%R0WCOUNT); CLOSE guru99_det; END: /
เอาท์พุต
Employee Fetched:BBB Employee Fetched:XXX Employee Fetched:YYY Total rows fetched is 3
คำอธิบายรหัส
- รหัสบรรทัดที่ 2: ประกาศเคอร์เซอร์ guru99_det สำหรับคำสั่ง 'SELECT emp_name FROM emp'
- รหัสบรรทัดที่ 3: ประกาศตัวแปร lv_emp_name
- รหัสบรรทัดที่ 5: เปิดเคอร์เซอร์ guru99_det.
- รหัสบรรทัด 6: การตั้งค่าคำสั่งลูปพื้นฐานเพื่อดึงข้อมูลบันทึกทั้งหมดในตาราง 'emp'
- รหัสบรรทัด 7: ดึงข้อมูล guru99_det และกำหนดค่าให้กับ lv_emp_name
- รหัสบรรทัด 9: การใช้แอตทริบิวต์เคอร์เซอร์ '%NOTFOUND' เพื่อค้นหาว่าดึงข้อมูลบันทึกทั้งหมดในเคอร์เซอร์หรือไม่ หากดึงข้อมูลมาก็จะคืนค่า 'TRUE' และการควบคุมจะออกจากลูป มิฉะนั้น การควบคุมจะดึงข้อมูลจากเคอร์เซอร์ต่อไปและพิมพ์ข้อมูล
- รหัสบรรทัด 11: เงื่อนไข EXIT สำหรับคำสั่งลูป
- รหัสบรรทัด 12: พิมพ์ชื่อพนักงานที่ดึงมา
- รหัสบรรทัด 14: การใช้แอตทริบิวต์เคอร์เซอร์ '%ROWCOUNT' เพื่อค้นหาจำนวนบันทึกทั้งหมดที่ได้รับผลกระทบ/ดึงข้อมูลในเคอร์เซอร์
- รหัสบรรทัด 15: หลังจากออกจากลูป เคอร์เซอร์จะปิดลง และหน่วยความจำที่จัดสรรจะถูกตั้งค่าให้ว่าง
สำหรับคำสั่งลูปเคอร์เซอร์
คำสั่ง “FOR LOOP” สามารถใช้สำหรับการทำงานกับเคอร์เซอร์ได้ เราสามารถตั้งชื่อเคอร์เซอร์แทนการจำกัดช่วงในคำสั่ง FOR loop เพื่อให้ลูปทำงานตั้งแต่บันทึกแรกของเคอร์เซอร์ไปจนถึงบันทึกสุดท้ายของเคอร์เซอร์ ตัวแปรเคอร์เซอร์ การเปิดเคอร์เซอร์ การดึงข้อมูลและการปิดเคอร์เซอร์จะกระทำโดยปริยายโดยลูป FOR
วากยสัมพันธ์
DECLARE CURSOR <cursor_name> IS <SELECT statement>; BEGIN FOR I IN <cursor_name> LOOP . . END LOOP; END;
- ในรูปแบบข้างต้น ส่วนการประกาศประกอบด้วยการประกาศของเคอร์เซอร์
- เคอร์เซอร์ถูกสร้างขึ้นสำหรับคำสั่ง 'SELECT' ที่กำหนดไว้ในการประกาศเคอร์เซอร์
- ในส่วนการดำเนินการ เคอร์เซอร์ที่ประกาศจะถูกตั้งค่าในลูป FOR และตัวแปรลูป 'I' จะทำงานเป็นตัวแปรเคอร์เซอร์ในกรณีนี้
Oracle เคอร์เซอร์สำหรับตัวอย่างลูป:
ในตัวอย่างนี้ เราจะฉายชื่อพนักงานทั้งหมดจากตาราง emp โดยใช้เคอร์เซอร์-FOR วนซ้ำ
DECLARE CURSOR guru99_det IS SELECT emp_name FROM emp; BEGIN FOR lv_emp_name IN guru99_det LOOP Dbms_output.put_line(‘Employee Fetched:‘||lv_emp_name.emp_name); END LOOP; END; /
เอาท์พุต
Employee Fetched:BBB Employee Fetched:XXX Employee Fetched:YYY
คำอธิบายรหัส
- รหัสบรรทัดที่ 2: ประกาศเคอร์เซอร์ guru99_det สำหรับคำสั่ง 'SELECT emp_name FROM emp'
- รหัสบรรทัดที่ 4: การสร้างลูป 'FOR' สำหรับเคอร์เซอร์ด้วยตัวแปรลูป lv_emp_name
- รหัสบรรทัด 5: การพิมพ์ชื่อพนักงานในการวนซ้ำแต่ละครั้ง
- รหัสบรรทัด 8: ออกจากวง
หมายเหตุ ใน Cursor-FOR loop แอ็ตทริบิวต์เคอร์เซอร์ไม่สามารถนำมาใช้ได้เนื่องจากการเปิด การดึงข้อมูล และการปิดเคอร์เซอร์ทำได้โดยปริยายโดย สำหรับห่วง.