Oracle แพ็คเกจ PL/SQL: ประเภท ข้อมูลจำเพาะ เนื้อหา [ตัวอย่าง]

แพ็คเกจในคืออะไร Oracle?

แพ็กเกจ PL/SQL คือการจัดกลุ่มเชิงตรรกะของซับโปรแกรมที่เกี่ยวข้อง (ขั้นตอน/ฟังก์ชัน) ให้เป็นองค์ประกอบเดียว แพ็กเกจจะถูกคอมไพล์และจัดเก็บเป็นอ็อบเจ็กต์ฐานข้อมูลที่สามารถนำมาใช้ในภายหลังได้

ส่วนประกอบของแพ็คเกจ

แพ็คเกจ PL/SQL มีสององค์ประกอบ

  • รายละเอียดแพ็คเกจ
  • แพคเกจร่างกาย

รายละเอียดแพ็คเกจ

ข้อมูลจำเพาะของแพ็คเกจประกอบด้วยการประกาศสาธารณะทั้งหมด ตัวแปร, เคอร์เซอร์, วัตถุ, ขั้นตอน, ฟังก์ชัน และข้อยกเว้น

ด้านล่างนี้คือคุณลักษณะบางประการของข้อกำหนดแพ็คเกจ

  • องค์ประกอบที่ประกาศไว้ในข้อกำหนดสามารถเข้าถึงได้จากภายนอกแพ็คเกจ องค์ประกอบดังกล่าวเรียกว่าองค์ประกอบสาธารณะ
  • ข้อมูลจำเพาะของแพ็คเกจเป็นองค์ประกอบแบบสแตนด์อโลนซึ่งหมายความว่าสามารถอยู่ได้โดยลำพังโดยไม่มีเนื้อหาของแพ็คเกจ
  • เมื่อใดก็ตามที่แพ็คเกจอ้างอิง อินสแตนซ์ของแพ็คเกจจะถูกสร้างขึ้นสำหรับเซสชันนั้น
  • หลังจากสร้างอินสแตนซ์สำหรับเซสชันแล้ว องค์ประกอบแพ็คเกจทั้งหมดที่เริ่มต้นในอินสแตนซ์นั้นจะใช้ได้จนกระทั่งสิ้นสุดเซสชัน

วากยสัมพันธ์

CREATE [OR REPLACE] PACKAGE <package_name> 
IS
<sub_program and public element declaration>
.
.
END <package name>

ไวยากรณ์ข้างต้นแสดงการสร้างข้อกำหนดแพ็คเกจ

แพคเกจร่างกาย

ประกอบด้วยคำจำกัดความขององค์ประกอบทั้งหมดที่มีอยู่ในข้อกำหนดแพ็คเกจ นอกจากนี้ยังสามารถมีคำจำกัดความขององค์ประกอบที่ไม่ได้ประกาศไว้ในข้อกำหนดองค์ประกอบเหล่านี้เรียกว่าองค์ประกอบส่วนตัวและสามารถเรียกได้จากภายในแพ็คเกจเท่านั้น

ด้านล่างนี้เป็นลักษณะของตัวบรรจุภัณฑ์

  • ควรมีคำจำกัดความของโปรแกรมย่อยทั้งหมด/เคอร์เซอร์ ที่ได้รับการประกาศไว้ในข้อกำหนดแล้ว
  • นอกจากนี้ยังอาจมีโปรแกรมย่อยเพิ่มเติมหรือองค์ประกอบอื่นๆ ที่ไม่ได้ประกาศไว้ในข้อกำหนด สิ่งเหล่านี้เรียกว่าองค์ประกอบส่วนตัว
  • เป็นวัตถุที่เชื่อถือได้ และขึ้นอยู่กับข้อกำหนดของแพ็คเกจ
  • สถานะของเนื้อหาของแพ็คเกจจะกลายเป็น 'ไม่ถูกต้อง' ทุกครั้งที่รวบรวมข้อกำหนด ดังนั้นจึงจำเป็นต้องทำการคอมไพล์ใหม่ทุกครั้งหลังจากการคอมไพล์ข้อมูลจำเพาะแล้ว
  • ควรกำหนดองค์ประกอบส่วนตัวก่อนจึงจะนำไปใช้ในส่วนของแพ็คเกจ
  • ส่วนแรกของแพ็คเกจคือส่วนการประกาศระดับโลก ซึ่งรวมถึงตัวแปร เคอร์เซอร์ และองค์ประกอบส่วนตัว (การประกาศไปข้างหน้า) ที่มองเห็นได้ทั่วทั้งแพ็คเกจ
  • ส่วนสุดท้ายของแพ็คเกจคือส่วนการเริ่มต้นแพ็คเกจที่ดำเนินการหนึ่งครั้งเมื่อใดก็ตามที่มีการอ้างอิงแพ็คเกจครั้งแรกในเซสชัน

ไวยากรณ์:

CREATE [OR REPLACE] PACKAGE BODY <package_name>
IS
<global_declaration part>
<Private element definition>
<sub_program and public element definition>
.
<Package Initialization> 
END <package_name>
  • ไวยากรณ์ข้างต้นแสดงการสร้างเนื้อความของแพ็คเกจ

ตอนนี้เราจะดูวิธีอ้างอิงองค์ประกอบแพ็คเกจในโปรแกรม

อ้างอิงองค์ประกอบแพ็คเกจ

เมื่อมีการประกาศและกำหนดองค์ประกอบในแพ็คเกจแล้ว เราจำเป็นต้องอ้างอิงองค์ประกอบต่างๆ เพื่อใช้งาน

องค์ประกอบสาธารณะทั้งหมดของแพ็คเกจสามารถอ้างอิงได้โดยการเรียกชื่อแพ็คเกจตามด้วยชื่อองค์ประกอบคั่นด้วยจุดเช่น ' - -

ตัวแปรสาธารณะของแพ็คเกจสามารถใช้ในลักษณะเดียวกันในการกำหนดและดึงค่าจากตัวแปรเหล่านั้น เช่น ' - -

สร้างแพ็คเกจใน PL/SQL

ใน PL/SQL เมื่อใดก็ตามที่มีการอ้างอิง/เรียกใช้แพ็คเกจในเซสชัน อินสแตนซ์ใหม่จะถูกสร้างขึ้นสำหรับแพ็คเกจนั้น

Oracle จัดเตรียมสิ่งอำนวยความสะดวกในการเริ่มต้นองค์ประกอบแพ็คเกจหรือดำเนินกิจกรรมใด ๆ ในขณะที่สร้างอินสแตนซ์นี้ผ่าน 'การเริ่มต้นแพ็คเกจ'

นี่ไม่ใช่อะไรเลยนอกจากบล็อกการดำเนินการที่เขียนไว้ในเนื้อหาของแพ็คเกจหลังจากกำหนดองค์ประกอบแพ็คเกจทั้งหมดแล้ว บล็อกนี้จะถูกดำเนินการทุกครั้งที่มีการอ้างอิงแพ็คเกจเป็นครั้งแรกในเซสชัน

วากยสัมพันธ์

สร้างแพ็คเกจใน PL/SQL

CREATE [OR REPLACE] PACKAGE BODY <package_name>
IS
<Private element definition>
<sub_program and public element definition>
.
BEGINE
<Package Initialization> 
END <package_name>
  • ไวยากรณ์ข้างต้นแสดงคำจำกัดความของการเริ่มต้นแพ็คเกจในเนื้อหาของแพ็คเกจ

ประกาศไปข้างหน้า

การประกาศ/อ้างอิงไปข้างหน้าในแพ็คเกจไม่ใช่สิ่งอื่นใดนอกจากการประกาศองค์ประกอบส่วนตัวแยกกันและกำหนดไว้ในส่วนหลังของเนื้อหาแพ็คเกจ

องค์ประกอบส่วนตัวสามารถอ้างอิงได้ก็ต่อเมื่อมีการประกาศไว้ในเนื้อหาของแพ็คเกจแล้ว ด้วยเหตุนี้ จึงมีการใช้การประกาศส่งต่อ แต่การใช้ค่อนข้างผิดปกติเพราะโดยส่วนใหญ่แล้วองค์ประกอบส่วนตัวจะถูกประกาศและกำหนดไว้ในส่วนแรกของเนื้อหาของแพ็คเกจ

การแจ้งล่วงหน้าเป็นทางเลือกที่จัดทำโดย Oracleมันไม่ได้บังคับ และการใช้และไม่ใช้ก็ขึ้นอยู่กับความต้องการของโปรแกรมเมอร์

ประกาศไปข้างหน้า

ไวยากรณ์:

CREATE [OR REPLACE] PACKAGE BODY <package_name>
IS
<Private element declaration>
.
.
.
<Public element definition that refer the above private element>
.
.
<Private element definition> 
.
BEGIN
<package_initialization code>; 
END <package_name>

รูปแบบข้างต้นแสดงการประกาศแบบส่งต่อ องค์ประกอบส่วนตัวจะถูกประกาศแยกกันในส่วนส่งต่อของแพ็คเกจ และได้รับการกำหนดไว้ในส่วนหลัง

การใช้เคอร์เซอร์ในแพ็คเกจ

แตกต่างจากองค์ประกอบอื่น ๆ ที่ต้องระมัดระวังในการใช้เคอร์เซอร์ภายในแพ็คเกจ

หากเคอร์เซอร์ถูกกำหนดไว้ในข้อกำหนดแพ็คเกจหรือในส่วนส่วนกลางของเนื้อหาแพ็คเกจ เมื่อเปิดเคอร์เซอร์แล้วจะคงอยู่จนกระทั่งสิ้นสุดเซสชัน

ดังนั้นเราควรใช้แอตทริบิวต์เคอร์เซอร์ '%ISOPEN' เพื่อตรวจสอบสถานะของเคอร์เซอร์ก่อนที่จะอ้างอิง

โอเวอร์โหลด

การโอเวอร์โหลดเป็นแนวคิดของการมีหลายโปรแกรมย่อยที่มีชื่อเดียวกัน โปรแกรมย่อยเหล่านี้จะแตกต่างกันตามจำนวนพารามิเตอร์หรือประเภทของพารามิเตอร์ หรือประเภทการส่งคืน เช่น โปรแกรมย่อยที่มีชื่อเดียวกันแต่มีจำนวนพารามิเตอร์ต่างกัน พารามิเตอร์ประเภทที่แตกต่างกัน หรือการพิมพ์ซ้ำที่แตกต่างกันจะถือเป็นการโอเวอร์โหลด

สิ่งนี้มีประโยชน์เมื่อโปรแกรมย่อยจำนวนมากจำเป็นต้องทำงานเดียวกัน แต่วิธีการเรียกแต่ละโปรแกรมควรแตกต่างกัน ในกรณีนี้ ชื่อโปรแกรมย่อยจะถูกเก็บไว้เหมือนกันสำหรับทุกคน และพารามิเตอร์จะถูกเปลี่ยนตามคำสั่งการโทร

1 ตัวอย่าง: ในตัวอย่างนี้ เราจะสร้างแพ็คเกจเพื่อรับและตั้งค่าข้อมูลพนักงานในตาราง 'emp' ฟังก์ชัน get_record จะส่งคืนเอาต์พุตประเภทบันทึกสำหรับหมายเลขพนักงานที่กำหนด และขั้นตอน set_record จะแทรกบันทึกประเภทบันทึกลงในตาราง emp

ขั้นตอน 1) การสร้างข้อกำหนดแพ็คเกจ

โอเวอร์โหลด

CREATE OR REPLACE PACKAGE guru99_get_set
IS
PROCEDURE set_record (p_emp_rec IN emp%ROWTYPE);
FUNCTION get record (p_emp no IN NUMBER) RETURN emp%ROWTYPE;
END guru99_get_set:
/

Output:

Package created

คำอธิบายรหัส

  • รหัสบรรทัด 1-5: การสร้างข้อกำหนดแพ็คเกจสำหรับ guru99_get_set ด้วยหนึ่งโพรซีเดอร์และหนึ่งฟังก์ชัน ตอนนี้ทั้งสองนี้เป็นองค์ประกอบสาธารณะของแพ็คเกจนี้

ขั้นตอน 2) แพ็คเกจประกอบด้วยเนื้อหาของแพ็คเกจ โดยที่ขั้นตอนและฟังก์ชันทั้งหมดจะกำหนดคำจำกัดความที่แท้จริง ในขั้นตอนนี้ Package Body จะถูกสร้างขึ้น

โอเวอร์โหลด

CREATE OR REPLACE PACKAGE BODY guru99_get_set
IS	
PROCEDURE set_record(p_emp_rec IN emp%ROWTYPE)
IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO emp
VALUES(p_emp_rec.emp_name,p_emp_rec.emp_no; p_emp_rec.salary,p_emp_rec.manager);
COMMIT;
END set_record;
FUNCTION get_record(p_emp_no IN NUMBER)
RETURN emp%ROWTYPE
IS
l_emp_rec emp%ROWTYPE;
BEGIN
SELECT * INTO l_emp_rec FROM emp where emp_no=p_emp_no
RETURN l_emp_rec;
END get_record;
BEGUN	
dbms_output.put_line(‘Control is now executing the package initialization part');
END guru99_get_set:
/

Output:

Package body created

คำอธิบายรหัส

  • รหัสบรรทัดที่ 7: การสร้างตัวแพ็คเกจ
  • รหัสบรรทัด 9-16: การกำหนดองค์ประกอบ 'set_record' ที่ถูกประกาศไว้ในข้อกำหนด สิ่งนี้เหมือนกับการกำหนดขั้นตอนแบบสแตนด์อโลนใน PL/SQL
  • รหัสบรรทัด 17-24: การกำหนดองค์ประกอบ 'get_record' มันเหมือนกับการกำหนดฟังก์ชันแบบสแตนด์อโลน
  • รหัสบรรทัด 25-26: การกำหนดส่วนการเริ่มต้นแพ็คเกจ

ขั้นตอน 3) การสร้างบล็อกที่ไม่ระบุชื่อเพื่อแทรกและแสดงบันทึกโดยอ้างอิงถึงแพ็คเกจที่สร้างขึ้นข้างต้น

โอเวอร์โหลด

DECLARE
l_emp_rec emp%ROWTYPE;
l_get_rec emp%ROWTYPE;
BEGIN
dbms output.put line(‘Insert new record for employee 1004');
l_emp_rec.emp_no:=l004;
l_emp_rec.emp_name:='CCC';
l_emp_rec.salary~20000;
l_emp_rec.manager:=’BBB’;
guru99_get_set.set_record(1_emp_rec);
dbms_output.put_line(‘Record inserted');
dbms output.put line(‘Calling get function to display the inserted record'):
l_get_rec:=guru99_get_set.get_record(1004);
dbms_output.put_line(‘Employee name: ‘||l_get_rec.emp_name);
dbms_output.put_line(‘Employee number:‘||l_get_rec.emp_no);
dbms_output.put_line(‘Employee salary:‘||l_get_rec.salary');
dbms output.put line(‘Employee manager:‘||1_get_rec.manager);		
END:
/

Output:

Insert new record for employee 1004
Control is now executing the package initialization part
Record inserted
Calling get function to display the inserted record
Employee name: CCC
Employee number: 1004
Employee salary: 20000
Employee manager: BBB

คำอธิบายรหัส:

  • รหัสบรรทัด 34-37: การเติมข้อมูลสำหรับตัวแปรประเภทบันทึกในบล็อกที่ไม่ระบุชื่อเพื่อเรียกองค์ประกอบ 'set_record' ของแพ็คเกจ
  • รหัสบรรทัด 38: โทรไปที่ 'set_record' ของแพ็คเกจ guru99_get_set แล้ว ตอนนี้แพ็คเกจได้รับการสร้างอินสแตนซ์แล้ว และจะคงอยู่จนกระทั่งสิ้นสุดเซสชัน
  • ส่วนการเริ่มต้นแพ็คเกจถูกดำเนินการเนื่องจากนี่เป็นการเรียกแพ็คเกจครั้งแรก
  • ระเบียนที่แทรกโดยองค์ประกอบ 'set_record' ลงในตาราง
  • รหัสบรรทัด 41: การเรียกใช้องค์ประกอบ 'get_record' เพื่อแสดงรายละเอียดของพนักงานที่แทรกเข้าไป
  • แพ็คเกจถูกอ้างอิงเป็นครั้งที่สองระหว่างการเรียก 'get_record' ไปยังแพ็คเกจ แต่ส่วนการเริ่มต้นไม่ได้ดำเนินการในครั้งนี้ เนื่องจากมีการเตรียมใช้งานแพ็คเกจแล้วในเซสชันนี้
  • รหัสบรรทัด 42-45: การพิมพ์รายละเอียดพนักงาน

การพึ่งพาในแพ็คเกจ

เนื่องจากแพ็กเกจเป็นกลุ่มตรรกะของสิ่งที่เกี่ยวข้องกัน จึงมีข้อกำหนดที่ต้องปฏิบัติตามบางประการ ต่อไปนี้คือข้อกำหนดที่ต้องปฏิบัติ

  • ข้อมูลจำเพาะเป็นวัตถุแบบสแตนด์อโลน
  • เนื้อหาของแพ็คเกจขึ้นอยู่กับข้อกำหนด
  • สามารถรวบรวมเนื้อหาของแพ็คเกจแยกกันได้ เมื่อใดก็ตามที่ข้อกำหนดถูกคอมไพล์ เนื้อความจะต้องถูกคอมไพล์ใหม่เนื่องจากจะไม่ถูกต้อง
  • โปรแกรมย่อยในเนื้อหาแพ็คเกจที่ขึ้นอยู่กับองค์ประกอบส่วนตัวควรถูกกำหนดหลังจากการประกาศองค์ประกอบส่วนตัวเท่านั้น
  • ออบเจ็กต์ฐานข้อมูลที่อ้างถึงในข้อกำหนดและเนื้อหาจะต้องมีสถานะที่ถูกต้อง ณ เวลาที่รวบรวมแพ็คเกจ

ข้อมูลแพ็คเกจ

เมื่อสร้างข้อมูลแพ็คเกจแล้ว ข้อมูลแพ็คเกจ เช่น แหล่งที่มาของแพ็คเกจ รายละเอียดโปรแกรมย่อย และรายละเอียดโอเวอร์โหลด จะพร้อมใช้งานใน Oracle ตารางคำจำกัดความของข้อมูล

ตารางด้านล่างแสดงตารางคำจำกัดความของข้อมูลและข้อมูลแพ็คเกจที่มีอยู่ในตาราง

ชื่อตาราง Descriptไอออน สอบถาม
ทั้งหมด_วัตถุ ให้รายละเอียดของแพ็กเกจ เช่น object_id, creation_date, last_ddl_time เป็นต้น ซึ่งจะมีอ็อบเจ็กต์ที่สร้างโดยผู้ใช้ทั้งหมด SELECT * จาก all_objects โดยที่ object_name =' -
USER_OBJECT ให้รายละเอียดของแพ็กเกจ เช่น object_id, creation_date, last_ddl_time เป็นต้น โดยจะมีวัตถุที่สร้างโดยผู้ใช้ปัจจุบัน SELECT * จาก user_objects โดยที่ object_name =' -
ทั้งหมด_แหล่งที่มา ให้แหล่งที่มาของวัตถุที่สร้างขึ้นโดยผู้ใช้ทั้งหมด SELECT * จาก all_source โดยที่ชื่อ =' -
USER_SOURCE ให้แหล่งที่มาของวัตถุที่สร้างขึ้นโดยผู้ใช้ปัจจุบัน SELECT * จาก user_source โดยที่ชื่อ =' -
ทั้งหมด_กระบวนการ ให้รายละเอียดโปรแกรมย่อยเช่น object_id, รายละเอียดโอเวอร์โหลด ฯลฯ ที่ถูกสร้างโดยผู้ใช้ทั้งหมด SELECT * จาก all_procedures
โดยที่ object_name=' -
USER_PROCEDURES ให้รายละเอียดโปรแกรมย่อยเช่น object_id, รายละเอียดโอเวอร์โหลด ฯลฯ ที่ถูกสร้างโดยผู้ใช้ปัจจุบัน SELECT * จาก user_procedures
โดยที่ object_name=' -

ไฟล์ UTL – ภาพรวม

ไฟล์ UTL เป็นแพ็คเกจยูทิลิตี้แยกต่างหากที่จัดทำโดย Oracle เพื่อดำเนินการงานพิเศษ โดยส่วนใหญ่ใช้สำหรับอ่านและเขียนไฟล์ระบบปฏิบัติการจากแพ็กเกจหรือซับโปรแกรม PL/SQL มีฟังก์ชันแยกต่างหากในการใส่ข้อมูลและรับข้อมูลจากไฟล์ นอกจากนี้ยังอนุญาตให้อ่าน/เขียนในชุดอักขระดั้งเดิมได้อีกด้วย

โปรแกรมเมอร์สามารถใช้สิ่งนี้เพื่อเขียนไฟล์ระบบปฏิบัติการประเภทใดก็ได้ และไฟล์จะถูกเขียนโดยตรงไปยังเซิร์ฟเวอร์ฐานข้อมูล ชื่อและเส้นทางไดเรกทอรีจะถูกระบุในขณะที่เขียน

สรุป

ตอนนี้เราได้เรียนรู้แพ็คเกจต่างๆแล้ว PL / SQLและตอนนี้คุณก็สามารถทำงานต่อไปนี้ได้แล้ว

  • แพ็คเกจ PL/SQL และส่วนประกอบต่างๆ
  • ลักษณะของบรรจุภัณฑ์
  • การอ้างอิงและการโอเวอร์โหลดองค์ประกอบแพ็คเกจ
  • การจัดการการพึ่งพาในแพ็คเกจ
  • การดูข้อมูลแพ็กเกจ
  • ไฟล์ UTL คืออะไร