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 โดยใช้เคอร์เซอร์ นอกจากนี้เรายังใช้แอตทริบิวต์เคอร์เซอร์เพื่อตั้งค่าการวนซ้ำเพื่อดึงข้อมูลบันทึกทั้งหมดจากเคอร์เซอร์

Oracle เคอร์เซอร์ PL/SQL

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 แอ็ตทริบิวต์เคอร์เซอร์ไม่สามารถนำมาใช้ได้เนื่องจากการเปิด การดึงข้อมูล และการปิดเคอร์เซอร์ทำได้โดยปริยายโดย สำหรับห่วง.