Oracle เคอร์เซอร์ PL/SQL: โดยนัย, ชัดเจน, สำหรับลูปพร้อมตัวอย่าง
⚡ สรุปอย่างชาญฉลาด
เคอร์เซอร์ใน Oracle เคอร์เซอร์ใน PL/SQL เป็นตัวชี้ไปยังพื้นที่บริบทที่เก็บแถวที่ส่งคืนโดยคำสั่ง SQL มีสองประเภท ได้แก่ เคอร์เซอร์โดยปริยาย ซึ่งสร้างขึ้นโดยอัตโนมัติสำหรับ DML และเคอร์เซอร์โดยชัดแจ้ง ซึ่งประกาศและควบคุมโดยโปรแกรมเมอร์

เคอร์เซอร์ใน PL/SQL คืออะไร?
เคอร์เซอร์คือตัวชี้ไปยังพื้นที่บริบท Oracle สร้างพื้นที่บริบทสำหรับการประมวลผล SQL ข้อความนี้ประกอบด้วยข้อมูลทั้งหมดเกี่ยวกับข้อความดังกล่าว
PL / SQL ช่วยให้โปรแกรมเมอร์สามารถควบคุมพื้นที่บริบทผ่านเคอร์เซอร์ได้ เคอร์เซอร์จะเก็บแถวที่ได้จากคำสั่ง SQL และชุดของแถวที่เคอร์เซอร์เก็บไว้เรียกว่าชุดที่ใช้งานอยู่ เคอร์เซอร์เหล่านี้ยังสามารถตั้งชื่อได้เพื่อให้สามารถอ้างอิงจากส่วนอื่นของโค้ดได้
เคอร์เซอร์มีสองประเภท:
- เคอร์เซอร์โดยปริยาย
- เคอร์เซอร์ที่ชัดเจน
เคอร์เซอร์โดยปริยาย
เมื่อใดก็ตามที่ การดำเนินการ DML เมื่อมีการดำเนินการใดๆ เกิดขึ้นในฐานข้อมูล จะมีการสร้างเคอร์เซอร์โดยปริยายขึ้นมา ซึ่งจะเก็บแถวข้อมูลที่ได้รับผลกระทบจากการดำเนินการนั้นๆ เคอร์เซอร์เหล่านี้ไม่สามารถตั้งชื่อได้ ดังนั้นจึงไม่สามารถควบคุมหรืออ้างอิงจากส่วนอื่นๆ ของโค้ดได้ เราสามารถอ้างอิงถึงเคอร์เซอร์ล่าสุดได้ผ่านทางแอตทริบิวต์ของเคอร์เซอร์เท่านั้น
เคอร์เซอร์ที่ชัดเจน
โปรแกรมเมอร์สามารถสร้างพื้นที่บริบทที่มีชื่อเพื่อดำเนินการคำสั่ง DML และควบคุมการทำงานได้มากขึ้น เคอร์เซอร์ที่ระบุอย่างชัดเจนควรถูกกำหนดไว้ในส่วนการประกาศของคลาส บล็อก PL/SQLและถูกสร้างขึ้นเพื่อใช้กับคำสั่ง SELECT ที่จำเป็นต้องใช้ในโค้ด
ต่อไปนี้คือขั้นตอนในการใช้งานเคอร์เซอร์แบบระบุเจาะจง:
- การประกาศเคอร์เซอร์: การประกาศเคอร์เซอร์หมายถึงการสร้างพื้นที่บริบทที่มีชื่อสำหรับคำสั่ง SELECT ที่กำหนดไว้ในส่วนของการประกาศ โดยชื่อของพื้นที่บริบทนี้จะเหมือนกับชื่อของเคอร์เซอร์
- การเปิดเคอร์เซอร์: การเปิดเคอร์เซอร์เป็นการสั่งให้ PL/SQL จัดสรรหน่วยความจำสำหรับเคอร์เซอร์นี้ ทำให้เคอร์เซอร์พร้อมสำหรับการดึงข้อมูล
- กำลังดึงข้อมูลจากเคอร์เซอร์: ในกระบวนการนี้ คำสั่ง SELECT จะถูกดำเนินการ และแถวที่ดึงมาจะถูกเก็บไว้ในหน่วยความจำที่จัดสรรไว้ ซึ่งตอนนี้เรียกว่าชุดข้อมูลที่ใช้งานอยู่ (active sets) การดึงข้อมูลจากเคอร์เซอร์เป็นกิจกรรมระดับเรคอร์ด ซึ่งหมายความว่าเราสามารถเข้าถึงข้อมูลได้ทีละเรคอร์ด คำสั่ง fetch แต่ละคำสั่งจะดึงชุดข้อมูลที่ใช้งานอยู่หนึ่งชุดและเก็บข้อมูลของเรคอร์ดนั้นๆ คำสั่งนี้เหมือนกับคำสั่ง 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 | ส่งคืนค่าตัวเลขที่แสดงจำนวนระเบียนที่ได้รับผลกระทบหรือดึงข้อมูลโดยการดำเนินการนั้นจริง |
ตัวอย่างการใช้เคอร์เซอร์แบบระบุชัดเจน: ในตัวอย่างนี้ เราจะมาดูวิธีการประกาศ เปิด ดึงข้อมูล และปิดเคอร์เซอร์แบบระบุชัดเจน เราจะดึงรายชื่อพนักงานทั้งหมดจากตาราง emp โดยใช้เคอร์เซอร์ นอกจากนี้ เราจะใช้แอตทริบิวต์ของเคอร์เซอร์เพื่อตั้งค่าลูปให้ดึงข้อมูลทั้งหมดจากเคอร์เซอร์
ภาพหน้าจอด้านล่างแสดงตัวอย่างเคอร์เซอร์แบบชัดเจนและผลลัพธ์ที่ได้ Oracle.
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%ROWCOUNT); CLOSE guru99_det; END; /
เอาท์พุต
Employee Fetched:BBB Employee Fetched:XXX Employee Fetched:YYY Total rows fetched is 3
Code คำอธิบาย
- Code สาย 2: ประกาศเคอร์เซอร์ guru99_det สำหรับคำสั่ง 'SELECT emp_name FROM emp'
- Code สาย 3: การประกาศตัวแปร lv_emp_name ด้วย %พิมพ์ ยึดโยงกับ emp.emp_name
- Code สาย 5: กำลังเปิดเคอร์เซอร์ guru99_det
- Code สาย 6: ตั้งค่าลูปพื้นฐานเพื่อดึงข้อมูลทั้งหมดในตาราง emp
- Code สาย 7: ดึงข้อมูล guru99_det และกำหนดค่าให้กับ lv_emp_name
- Code สาย 8: ใช้แอตทริบิวต์ %NOTFOUND ของเคอร์เซอร์เพื่อตรวจสอบว่าดึงข้อมูลทั้งหมดในเคอร์เซอร์มาแล้วหรือไม่ ถ้าดึงมาแล้ว จะส่งค่า TRUE กลับมา และการควบคุมจะออกจากลูป มิเช่นนั้น การควบคุมจะดึงข้อมูลจากเคอร์เซอร์ต่อไปและแสดงผล
- Code สาย 10: เงื่อนไข EXIT สำหรับคำสั่งลูป
- Code สาย 12: พิมพ์ชื่อพนักงานที่ดึงมา
- Code สาย 14: ใช้แอตทริบิวต์เคอร์เซอร์ %ROWCOUNT เพื่อหาจำนวนระเบียนทั้งหมดที่เคอร์เซอร์ดึงมาได้
- Code สาย 15: หลังจากออกจากลูปแล้ว เคอร์เซอร์จะถูกปิด และหน่วยความจำที่จัดสรรไว้จะถูกปล่อยให้ว่าง
สำหรับคำสั่งลูปเคอร์เซอร์
เคอร์เซอร์ สำหรับห่วง สามารถใช้สำหรับการทำงานกับเคอร์เซอร์ได้ เราสามารถกำหนดชื่อเคอร์เซอร์แทนการกำหนดช่วงในคำสั่งลูป FOR เพื่อให้ลูปทำงานตั้งแต่เรคอร์ดแรกของเคอร์เซอร์ไปจนถึงเรคอร์ดสุดท้ายของเคอร์เซอร์ ตัวแปรเคอร์เซอร์ การเปิดเคอร์เซอร์ การดึงข้อมูล และการปิดเคอร์เซอร์ จะดำเนินการโดยปริยายด้วยลูป FOR
วากยสัมพันธ์
DECLARE CURSOR <cursor_name> IS <SELECT statement>; BEGIN FOR I IN <cursor_name> LOOP . . END LOOP; END;
ในไวยากรณ์ข้างต้น ส่วนการประกาศประกอบด้วยการประกาศเคอร์เซอร์ เคอร์เซอร์ถูกสร้างขึ้นสำหรับคำสั่ง SELECT ที่ระบุไว้ในการประกาศเคอร์เซอร์ ในส่วนการทำงาน เคอร์เซอร์ที่ประกาศไว้จะถูกตั้งค่าในลูป FOR และตัวแปรลูป 'I' จะทำหน้าที่เป็นตัวแปรเคอร์เซอร์ในกรณีนี้
Oracle ตัวอย่างการใช้เคอร์เซอร์สำหรับลูป: ในตัวอย่างนี้ เราจะแสดงรายชื่อพนักงานทั้งหมดจากตาราง emp โดยใช้ลูป cursor-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
Code คำอธิบาย
- Code สาย 2: ประกาศเคอร์เซอร์ guru99_det สำหรับคำสั่ง 'SELECT emp_name FROM emp'
- Code สาย 4: สร้างลูป FOR สำหรับเคอร์เซอร์โดยใช้ตัวแปรลูป lv_emp_name
- Code สาย 6: การพิมพ์ชื่อพนักงานในการวนซ้ำแต่ละครั้ง
- Code สาย 7: ออกจากลูป (END LOOP)
หมายเหตุ ในลูป FOR ที่ใช้เคอร์เซอร์นั้น ไม่สามารถใช้แอตทริบิวต์ของเคอร์เซอร์ได้ เนื่องจากลูป FOR จะทำการเปิด ดึงข้อมูล และปิดเคอร์เซอร์โดยปริยายอยู่แล้ว

