در ادامه آموزش PL/SQL، در این قسمت پکیج (PACKAGE) را توضیح می دهیم. پکیج یکی از OBJECT های دیتابیس اوراکل است که متغیرها، زیربرنامه ها و … که از لحاظ منطقی به هم مرتبط هستند را در یک گروه قرار می دهد.
برای هر پکیج دو قسمت تعریف می شود:
1.قسمت مشخصات پکیج یا PACKAGE SPECIFICATION
2.قسمت بدنه پکیج یا (PACKAGE BODY(DEFINITION
در ادامه این دو قسمت را توضیح می دهیم.
مشخصات پکیج(SPEC)
قسمت مشخصات یا SPEC یک واسط (INTERFACE) به محیط بیرون از پکیج است و در این قسمت OBJECTهایی مانند متغیر، نوع داده ، CONSTANT، EXCEPTION، CURSOR و زیربرنامه تعریف می شوند که می توان از بیرون پکیج آنها را فراخوانی کرد. در واقع قسمت SPEC، شامل اطلاعات اصلی پکیج به جز کد مربوط به زیربرنامه ها و CURSORها است.
تمام OBJECTهایی که در قسمت مشخصات پکیج قرار دارند و از محیط بیرون قابل دسترس هستند PUBLIC نامیده می شوند و OBJECTهای که در قسمت بدنه پکیج تعریف شده اند یک OBJECT از نوع PRIVATE نامیده می شود و فقط در حوزه همان پکیج قابل اجرا خواهد بود.
مثال: قسمت مشخصات پکیج برای پکیج cust_sal را ایجاد کنید که شامل یک زیربرنامه به نام find_sal است.
CREATE PACKAGE cust_sal AS
PROCEDURE find_sal(c_id customers.id%type);
END cust_sal;
/
Package created.
بدنه پکیج
اگر در قسمت مشخصات یا SPEC یک پکیج از زیربرنامه یا CURSOR استفاده شده باشد می بایست از قسمت بدنه استفاده نمود تا کد برنامه مربوط به آنها در پکیج تعریف شود. در این قسمت می توان OBJECT هایی مانند متغیرها، زیربرنامه ها و … را تعریف نمود که در قسمت مشخصات پکیج نوشته نشده باشند ولی این OBJECTها از محیط بیرون از بدنه پکیج قابل دسترس نمی باشند.
مثال: قسمت بدنه برای پکیج cust_sal را ایجاد کنید. همانطور که می بینید کد مربوط به زیربرنامه find_sal در این قسمت تعریف می شود.
CREATE OR REPLACE PACKAGE BODY cust_sal AS
PROCEDURE find_sal(c_id customers.id%TYPE) IS
c_sal customers.salary%TYPE;
BEGIN
SELECT salary INTO c_sal
FROM customers
WHERE id = c_id;
dbms_output.put_line(‘Salary: ‘|| c_sal);
END find_sal;
END cust_sal;
/
Package body created.
چرا از پکیج استفاده می شود؟
1.با استفاده از پکیج، کد نویسی به روش ماژولار انجام می گیرد.
2.پنهان سازی جزییات پیاده سازی بدلیل ذخیره و تغییر کد برنامه در قسمت بدنه.
3.بهبود PERFORMANCE از آنجایی که با اولین دسترسی به پکیج تمام محتویات پکیج در حافظه فیزیکی قرار می گیرد.
4.می توان OBJECTهای مختلف (پروسیجر، تابع و …) را در داخل یک پکیج تعریف کرد و یک GRANT کلی بر روی آن پکیج به کاربر مورد نظر داد.
استفاده از اجزای پکیج
اجزای پکیج از جمله توابع، پروسیجرها و متغیرها که در قسمت مشخصات پکیج عنوان شده اند با علامت . قابل دسترس و فراخوانی هستند:
package_name.element_name;
مثال 1: از متود find_sal که در پکیج cust_sal تعریف شده است استفاده کنید.
DECLARE
code customers.id%type := &cc_id;
BEGIN
cust_sal.find_sal(code);
END;
/
خروجی
Enter value for cc_id: 1
Salary: 3000
PL/SQL procedure successfully completed.
مثال 2:جدول customers را در نظر بگیرید:
Select * from customers;
+—-+———-+—–+———–+———-+
| ID | NAME | AGE | ADDRESS | SALARY |
+—-+———-+—–+———–+———-+
| 1 | Ramesh | 32 | Ahmedabad | 3000.00 |
| 2 | Khilan | 25 | Delhi | 3000.00 |
| 3 | kaushik | 23 | Kota | 3000.00 |
| 4 | Chaitali | 25 | Mumbai | 7500.00 |
| 5 | Hardik | 27 | Bhopal | 9500.00 |
| 6 | Komal | 22 | MP | 5500.00 |
+—-+———-+—–+———–+———-+
قسمت مشخصات پکیج را تعریف کنید:
CREATE OR REPLACE PACKAGE c_package AS
— Adds a customer
PROCEDURE addCustomer(c_id customers.id%type,
c_name customerS.name%type,
c_age customers.age%type,
c_addr customers.address%type,
c_sal customers.salary%type);
— Removes a customer
PROCEDURE delCustomer(c_id customers.id%TYPE);
–Lists all customers
PROCEDURE listCustomer;
END c_package;
/
Package created.
قسمت بدنه پکیج را تعریف کنید:
CREATE OR REPLACE PACKAGE BODY c_package AS
PROCEDURE addCustomer(c_id customers.id%type,
c_name customerS.name%type,
c_age customers.age%type,
c_addr customers.address%type,
c_sal customers.salary%type)
IS
BEGIN
INSERT INTO customers (id,name,age,address,salary)
VALUES(c_id, c_name, c_age, c_addr, c_sal);
END addCustomer;
PROCEDURE delCustomer(c_id customers.id%type) IS
BEGIN
DELETE FROM customers
WHERE id = c_id;
END delCustomer;
PROCEDURE listCustomer IS
CURSOR c_customers is
SELECT name FROM customers;
TYPE c_list is TABLE OF customerS.name%type;
name_list c_list := c_list();
counter integer :=0;
BEGIN
FOR n IN c_customers LOOP
counter := counter +1;
name_list.extend;
name_list(counter) := n.name;
dbms_output.put_line(‘Customer(‘ ||counter|| ‘)’||name_list(counter));
END LOOP;
END listCustomer;
END c_package;
/
Package body created.
از متودهایی که در پکیج فوق تعریف شده است استفاده کنید.
DECLARE
code customers.id%type:= 8;
BEGIN
c_package.addcustomer(7, ‘Rajnish’, 25, ‘Chennai’, 3500);
c_package.addcustomer(8, ‘Subham’, 32, ‘Delhi’, 7500);
c_package.listcustomer;
c_package.delcustomer(code);
c_package.listcustomer;
END;
/
خروجی
Customer(1): Ramesh
Customer(2): Khilan
Customer(3): kaushik
Customer(4): Chaitali
Customer(5): Hardik
Customer(6): Komal
Customer(7): Rajnish
Customer(8): Subham
Customer(1): Ramesh
Customer(2): Khilan
Customer(3): kaushik
Customer(4): Chaitali
Customer(5): Hardik
Customer(6): Komal
Customer(7): Rajnish
PL/SQL procedure successfully completed
با تشکر، آیا امکانش هست که به یک یوزر، اجازه create or replace را فقط برای یکی از پکیج های اسکیمای خودمان بدهیم ؟
با سلام خدمت شما دوست عزیر، در دیتابیس اوراکل فقط اجازه یا grant برای EXECUTE و DEBUG را می توان برای یک پکیج خاص تعین کرد ولی برای CREATE OR REPLACE یک پکیج می بایست مجوز کلی EDIT روی تمام پکیج ها را به کاربر مورد نظر داد.
ممنونم از پاسخ شما