Oracle أنواع كائنات PL/SQL: إنشاء نوع مع أمثلة
⚡ ملخص ذكي
تُتيح أنواع الكائنات في لغة PL/SQL إمكانية البرمجة الكائنية التوجه. Oracleتتيح لك هذه الميزة نمذجة الكيانات الواقعية باستخدام السمات والأساليب. وهي تدعم المُنشئات، والوراثة، ومقارنة المساواة، بحيث يمكن لنوع واحد على مستوى المخطط تخزين ومعالجة البيانات المهيكلة.
ما هو نوع الكائن في PL/SQL؟
تُعدّ البرمجة كائنية التوجه مناسبةً بشكلٍ خاص لبناء مكونات قابلة لإعادة الاستخدام وتطبيقات معقدة. تُنظّم البرامج حول "الكائنات" بدلاً من "الإجراءات"؛ أي أنها مصممة للعمل والتفاعل مع كائن كامل بدلاً من إجراء واحد. يُمكّن هذا النهج المبرمج من ملء التفاصيل ومعالجتها على مستوى كيان الكائن.
تُظهر الصورة أدناه مثالاً على نوع كائن يُعامل فيه الحساب المصرفي ككيان كائن. تحتوي سمات الكائن على قيم - بالنسبة للحساب المصرفي، تشمل هذه القيم رقم الحساب، ورصيد الحساب، وما إلى ذلك - بينما تصف أساليب الكائن إجراءات مثل حساب سعر الفائدة أو إنشاء كشف حساب مصرفي، ويتطلب كل منها عملية لإتمامها.
In PL / SQLتعتمد البرمجة كائنية التوجه على أنواع الكائنات. يمكن لنوع الكائن أن يمثل أي كيان من كيانات العالم الحقيقي. تستكشف الأقسام التالية أنواع الكائنات ومكوناتها وكيفية إنشائها واستخدامها.
مكونات أنواع الكائنات
يحتوي نوع كائن PL/SQL بشكل أساسي على مكونين.
- السمات
- الأعضاء/الأساليب
السمات
السمات هي الأعمدة أو الحقول التي تُخزَّن فيها البيانات. تُربط كل سمة بنوع البيانات الذي يُحدد نوع المعالجة والتخزين لتلك السمة. يمكن أن تكون السمة من أي نوع بيانات صالح. نوع البيانات بل/SQLأو يمكن أن يكون من نوع كائن آخر.
الأعضاء/الأساليب
الأعضاء، أو الأساليب، هم البرامج الفرعية تُعرَّف هذه الخصائص داخل نوع الكائن. ولا تُستخدم لتخزين البيانات، بل لتحديد العمليات التي تُجرى داخل نوع الكائن، مثل التحقق من صحة البيانات قبل ملء الكائن. تُصرَّح هذه الخصائص في مواصفات نوع الكائن وتُعرَّف في جسم نوع الكائن. الجسم اختياري: إذا لم تكن هناك خصائص، فإن نوع الكائن لا يحتوي على جزء جسم.
إنشاء كائن في Oracle
لا يمكن إنشاء نوع كائن على مستوى البرنامج الفرعي، بل على مستوى المخطط فقط. بمجرد تعريف نوع الكائن في المخطط، يمكن استخدامه في البرامج الفرعية. يُنشأ نوع الكائن باستخدام عبارة "CREATE TYPE"، ولا يمكن إنشاء جسم النوع إلا بعد وجود نوع الكائن الخاص به.
تُظهر لقطات الشاشة أدناه صيغة CREATE TYPE لمواصفات الكائن وصيغة CREATE TYPE BODY التي تحدد أساليبه.
CREATE TYPE<object_type_name> AS OBJECT ( <attribute_l><datatype>, . . ); / CREATE TYPE BODY<object_type_name> AS OBJECT ( MEMBER[PROCEDURE|FUNCTION]<member_name> IS <declarative section> BEGIN <execution part> END; . . ); /
شرح بناء الجملة:
- يوضح التركيب النحوي أعلاه إنشاء كائن ذي سمات وجسم كائن ذي أساليب.
- يمكن أيضًا تحميل الأساليب بشكل زائد في نص الكائن.
تهيئة الإعلان عن نوع الكائن
كما هو الحال مع المكونات الأخرى في لغة PL/SQL، يجب تعريف أنواع الكائنات قبل استخدامها في البرنامج. بمجرد إنشاء نوع الكائن، يمكن استخدامه في قسم التعريف الخاص بالبرنامج الفرعي لتعريف متغير من هذا النوع.
عند تعريف متغير كنوع كائن، يتم إنشاء نسخة جديدة من هذا النوع أثناء التشغيل، ويُشار إلى هذه النسخة الجديدة باسم المتغير. وبهذه الطريقة، يمكن لنوع كائن واحد تخزين قيم متعددة ضمن نسخ مختلفة.
تُظهر لقطة الشاشة أدناه متغيرًا يتم تعريفه كنوع كائن داخل كتلة بل/SQL.
DECLARE <variable_name> <object_type_name>; BEGIN . . END; /
شرح بناء الجملة:
- يوضح التركيب النحوي أعلاه تعريف a متغير كنوع كائن في القسم التصريحي.
بمجرد تعريف المتغير كنوع كائن في برنامج فرعي، يصبح فارغًا تمامًا - أي أن الكائن بأكمله فارغ. يجب تهيئته بقيم قبل استخدامه في البرنامج. تتم تهيئة الكائنات باستخدام الدوال البانية.
الدوال البانية هي الدوال الضمنية للكائن والتي يمكن الإشارة إليها بنفس اسم نوع الكائن. تُظهر لقطة الشاشة أدناه عملية تهيئة نسخة من نوع كائن.
DECLARE <variable_name> <object_type_name>; BEGIN <variable_name>:=<object_type_name>(); END; /
شرح بناء الجملة:
- يوضح التركيب النحوي أعلاه تهيئة مثيل نوع الكائن بقيمة فارغة (null).
- لم يعد الكائن نفسه فارغًا بمجرد تهيئته، ولكن تظل السمات الموجودة داخل الكائن فارغة حتى يتم تعيين قيم لها.
الصانعين
الدوال البانية هي طرق ضمنية للكائن يمكن الإشارة إليها بنفس اسم نوع الكائن. عند الإشارة إلى الكائن لأول مرة، يتم استدعاء هذه الدالة البانية ضمنيًا.
يمكنك أيضًا تهيئة الكائنات باستخدام هذه الدوال البانية. ويمكن تعريف الدالة البانية بشكل صريح عن طريق تعريف عضو في جسم نوع الكائن يحمل نفس اسم نوع الكائن.
مثال 1: في المثال التالي، نستخدم عضو نوع الكائن لإدراج سجلات في جدول الموظفين بالقيمتين ('RRR', 1005, 20000, 1000) و('PPP', 1006, 20000, 1001). بعد إدراج البيانات، نعرضها باستخدام عضو نوع الكائن. كما نستخدم مُنشئًا صريحًا لتعبئة معرّف المدير بالقيمة الافتراضية 1001 للسجل الثاني.
نقوم بتنفيذ ذلك في الخطوات التالية.
- الخطوة 1: إنشاء نوع الكائن وجسم نوع الكائن.
- الخطوة 2: إنشاء كتلة مجهولة لاستدعاء نوع الكائن من خلال المُنشئ الضمني لـ emp_no 1005.
- الخطوة 3: إنشاء كتلة مجهولة لاستدعاء نوع الكائن من خلال المُنشئ الصريح لـ emp_no 1006.
الخطوة 1) إنشاء نوع الكائن وجسم نوع الكائن.
تُظهر لقطة الشاشة أدناه مواصفات نوع الكائن emp_object التي يتم إنشاؤها مع سماتها وأعضائها.
CREATE TYPE emp_object AS OBJECT( emp_no NUMBER, emp_name VARCHAR2(50), salary NUMBER, manager NUMBER, CONSTRUCTOR FUNCTION emp_object(p_emp_no NUMBER, p_emp_name VARCHAR2, p_salary NUMBER) RETURN SELF AS RESULT), MEMBER PROCEDURE insert_records, MEMBER PROCEDURE display_records); /
تُظهر لقطة الشاشة أدناه إنشاء جسم نوع emp_object باستخدام المُنشئ الصريح وإجراءات الأعضاء.
CREATE OR REPLACE TYPE BODY emp_object AS CONSTRUCTOR FUNCTION emp_object(p_emp_no NUMBER,p_emp_name VARCHAR2, p_salary NUMBER) RETURN SELF AS RESULT IS BEGIN Dbms_output.put_line('Constructor fired..'); SELF.emp_no:=p_emp_no; SELF.emp_name:=p_emp_name; SELF.salary:=p_salary; SELF.manager:=1001; RETURN; END; MEMBER PROCEDURE insert_records IS BEGIN INSERT INTO emp VALUES(emp_no,emp_name,salary,manager); END; MEMBER PROCEDURE display_records IS BEGIN Dbms_output.put_line('Employee Name:'||emp_name); Dbms_output.put_line('Employee Number:'||emp_no); Dbms_output.put_line('Salary:'||salary); Dbms_output.put_line('Manager:'||manager); END; END; /
Code تفسير
- Code الأسطر 1-9: إنشاء نوع الكائن 'emp_object' بأربعة خصائص وثلاثة أعضاء. يحتوي هذا النوع على تعريف دالة إنشاء بثلاثة معاملات فقط. (تحتوي دالة الإنشاء الضمنية الفعلية على عدد من المعاملات يساوي عدد الخصائص الموجودة في نوع الكائن).
- Code السطر 10: إنشاء نص النوع.
- Code الأسطر 11-21: تحديد المُنشئ الصريح. تعيين قيم المعلمات للسمات وتعيين القيمة الافتراضية '1001' للسمة 'manager'.
- Code الأسطر 22-26: تعريف العضو 'insert_records'، الذي يتم فيه إدراج قيم السمات في جدول 'emp'.
- Code الأسطر 27-34: تعريف العضو 'display_records'، الذي يعرض قيم سمات نوع الكائن.
الإخراج:
تم إنشاء النوع
نوع الجسم الذي تم إنشاؤه
الخطوة 2) إنشاء كتلة مجهولة لاستدعاء نوع الكائن الذي تم إنشاؤه من خلال المُنشئ الضمني لـ emp_no 1005.
تُظهر لقطة الشاشة أدناه الكتلة المجهولة التي تستدعي emp_object من خلال المُنشئ الضمني.
DECLARE guru_emp_det emp_object; BEGIN guru_emp_det:=emp_object(1005,'RRR',20000,1000); guru_emp_det.display_records; guru_emp_det.insert_records; COMMIT; END;
Code تفسير
- Code الأسطر 37-45: يتم إدراج السجلات باستخدام المُنشئ الضمني. يحتوي استدعاء المُنشئ على العدد الفعلي لقيم السمات.
- Code السطر 38: يُعلن عن 'guru_emp_det' كنوع كائن 'emp_object'.
- Code السطر 41: يستدعي البيان 'guru_emp_det.display_records' العضو 'display_records' ويتم عرض قيم السمات.
- Code السطر 42: يستدعي الأمر 'guru_emp_det.insert_records' العضو 'insert_records' ويتم إدراج قيم السمات في الجدول. ثم يقوم البرنامج بتنفيذ عملية الالتزام. صفقة.
الإخراج:
اسم الموظف: RRR
رقم الموظف: 1005
الراتب: 20000
المدير: 1000
الخطوة 3) إنشاء كتلة مجهولة لاستدعاء نوع الكائن الذي تم إنشاؤه من خلال المُنشئ الصريح لـ emp_no 1006.
تُظهر لقطة الشاشة أدناه الكتلة المجهولة التي تستدعي emp_object من خلال المُنشئ الصريح بثلاثة وسائط.
DECLARE guru_emp_det emp_object; BEGIN guru_emp_det:=emp_object(1006,'PPP',20000); guru_emp_det.display_records; guru_emp_det.insert_records; COMMIT; END; /
الناتج
Employee Name:PPP Employee Number:1006 Salary:20000 Manager:1001
Code التفسير:
- Code الأسطر 46-53: إدراج السجل باستخدام المُنشئ الصريح.
- Code السطر 46: يُعلن عن 'guru_emp_det' كنوع كائن 'emp_object'.
- Code السطر 50: يستدعي البيان 'guru_emp_det.display_records' العضو 'display_records' ويتم عرض قيم السمات.
- Code السطر 51: يستدعي الأمر 'guru_emp_det.insert_records' العضو 'insert_records'، ويتم إدراج قيم السمات في الجدول. ولأن ثلاثة وسائط فقط يتم تمريرها، يقوم المُنشئ الصريح بتعيين مُعرّف المدير إلى قيمته الافتراضية 1001.
الوراثة في نوع الكائن
تتيح خاصية الوراثة لنوع الكائن الفرعي الوصول إلى جميع سمات وأعضاء نوع الكائن الرئيسي، أو نوع الكائن الأصل.
يُسمى نوع الكائن الفرعي بنوع الكائن الموروث، ويُسمى نوع الكائن الرئيسي بنوع الكائن الأصل. يوضح الشكل أدناه كيفية إنشاء أنواع الكائنات الأصلية والموروثة. تُظهر لقطة الشاشة أدناه صيغة النوع الأصل (SUPER) مع وضع علامة "غير نهائي" عليها.
CREATE TYPE <object_type_name_parent> AS OBJECT ( <attribute_l><datatype>, . . )NOT FINAL; /
شرح بناء الجملة:
- يوضح التركيب أعلاه كيفية إنشاء النوع SUPER. تسمح عبارة NOT FINAL بتوريث هذا النوع.
تُظهر لقطة الشاشة أدناه صيغة النوع الموروث (SUB) التي تم إنشاؤها باستخدام الكلمة المفتاحية UNDER.
CREATE TYPE<object_type_name_sub>UNDER<object_type_name_parent> ( <attribute_l><datatype>, . ); /
شرح بناء الجملة:
- يوضح التركيب النحوي أعلاه كيفية إنشاء النوع الفرعي. وهو يحتوي على جميع الأعضاء والخصائص من نوع الكائن الأصل.
مثال 1: في المثال أدناه، نستخدم خاصية التوريث لإدراج سجل برقم تعريف المدير '1002' للسجل ('RRR', 1007, 20000). ننفذ البرنامج وفق الخطوات التالية.
- الخطوة 1: إنشاء النوع الفائق.
- الخطوة الثانية: إنشاء النوع الفرعي والجسم.
- الخطوة 3: إنشاء كتلة مجهولة لاستدعاء النوع الفرعي.
الخطوة 1) إنشاء نوع رئيسي أو نوع أب.
تُظهر لقطة الشاشة أدناه إنشاء النوع الفائق emp_object باستخدام عبارة NOT FINAL.
CREATE TYPE emp_object AS OBJECT( emp_no NUMBER, emp_name VARCHAR2(50), salary NUMBER, manager NUMBER, CONSTRUCTOR FUNCTION emp_object(p_emp_no NUMBER,p_emp_name VARCHAR2(50), p_salary NUMBER)RETURN SELF AS RESULT), MEMBER PROCEDURE insert_records, MEMBER PROCEDURE display_records)NOT FINAL; /
Code التفسير:
- Code الأسطر 1-9: إنشاء نوع الكائن 'emp_object' بأربعة خصائص وثلاثة أعضاء. يحتوي على تعريف دالة إنشاء بثلاثة معاملات فقط. تم تعريفه على أنه 'غير نهائي'، لذا فهو نوع أب.
الخطوة 2) إنشاء نوع فرعي ضمن النوع الرئيسي.
تُظهر لقطة الشاشة أدناه النوع الموروث sub_emp_object وجسمه أثناء إنشائه.
CREATE OR REPLACE TYPE sub_emp_object UNDER emp_object (default_manager NUMBER,MEMBER PROCEDURE insert_default_mgr); / CREATE OR REPLACE TYPE BODY sub_emp_object AS MEMBER PROCEDURE insert_default_mgr IS BEGIN INSERT INTO emp VALUES(emp_no,emp_name,salary,manager); END; END; /
Code التفسير:
- Code الأسطر 10-13: إنشاء 'sub_emp_object' كنوع موروث مع سمة إضافية واحدة 'default_manager' وإعلان إجراء عضو.
- Code السطر 14: إنشاء جسم نوع الكائن الموروث.
- Code الأسطر 16-21: يُعرّف هذا الإجراء الخاص بالعضو الذي يُدرج السجلات في جدول 'emp' بالقيم من نوع الكائن SUPER، باستثناء قيمة المدير. بالنسبة لقيمة المدير، فإنه يستخدم 'default_manager' من نوع SUB.
الخطوة 3) إنشاء كتلة مجهولة لاستدعاء النوع الفرعي.
تُظهر لقطة الشاشة أدناه الكتلة المجهولة التي تستدعي النوع الفرعي وتُدرج معرّف المدير الافتراضي.
DECLARE guru_emp_det sub_emp_object; BEGIN guru_emp_det:= sub_emp_object(1007,'RRR',20000,1000,1002); guru_emp_det.insert_default_mgr; COMMIT; END; /
Code التفسير:
- Code السطر 25: تعريف 'guru_emp_det' كنوع 'sub_emp_object'.
- Code السطر 27: يتم تهيئة الكائن باستخدام المُنشئ الضمني. يحتوي المُنشئ على 5 مُعاملات (4 سمات من النوع الأصل وسمة واحدة من النوع الفرعي). يُحدد المُعامل الأخير (1002) قيمة السمة default_manager.
- Code السطر 28: استدعاء العضو 'insert_default_mgr' لإدراج السجل باستخدام معرف المدير الافتراضي الذي تم تمريره في المُنشئ.
المساواة بين كائنات PL/SQL
يمكن مقارنة مثيلات الكائنات التي تنتمي إلى نفس نوع الكائن للتأكد من تساويها. وللقيام بذلك، يحتاج نوع الكائن إلى دالة خاصة تُسمى دالة الترتيب (ORDER).
يجب أن تكون دالة ORDER هذه دالة تُرجع قيمة عددية. تأخذ هذه الدالة مُعاملين كمدخلات (المُعامل الأول: مُعرّف نسخة الكائن الذاتي؛ المُعامل الثاني: مُعرّف نسخة كائن آخر).
تتم مقارنة معرفات مثيلات الكائنين، ويتم إرجاع النتيجة كرقم.
- تشير القيمة الموجبة إلى أن نسخة الكائن SELF أكبر من النسخة الأخرى.
- تشير القيمة السالبة إلى أن نسخة الكائن SELF أقل من النسخة الأخرى.
- يشير الصفر إلى أن نسخة الكائن SELF تساوي النسخة الأخرى.
- إذا كانت أي من الحالتين فارغة، فإن الدالة تُرجع قيمة فارغة.
تُظهر لقطة الشاشة أدناه صيغة دالة العضو ORDER التي يجب تضمينها في جسم النوع لإجراء فحص المساواة.
CREATE TYPE BODY<object_type_name_ 1>AS OBJECT ( ORDER MEMBER FUNCTION match(<parameter> object_type_name_ 1) RETURN INTEGER IS BEGIN IF <attribute_name>parameter <attribute_name>THEN RETURN -1; --any negative number will do ELSIF id>c.id THEN RETURN 1; --any positive number will do ELSE RETURN 0; END IF; END; . . ); /
شرح بناء الجملة:
- يوضح التركيب النحوي أعلاه دالة ORDER التي يجب تضمينها في نص النوع لإجراء فحص المساواة.
- يجب أن تكون معلمة هذه الوظيفة مثيلًا لنفس نوع الكائن.
- يمكن استدعاء الدالة على النحو التالي "obj_instance_1.match(obj_instance_2)"، ويعيد هذا التعبير القيمة العددية الموضحة، حيث أن obj_instance_1 و obj_instance_2 هما مثيلان لنوع الكائن.
مثال 1: في المثال التالي، نقارن بين كائنين. نقوم بإنشاء نسختين منهما ونقارن سمة "الراتب" بينهما. نقوم بذلك على مرحلتين.
- الخطوة 1: إنشاء نوع الكائن وجسمه.
- الخطوة الثانية: إنشاء الكتلة المجهولة لمقارنة مثيلات الكائنات.
الخطوة 1) إنشاء نوع الكائن وجسمه.
تُظهر لقطات الشاشة أدناه مواصفات emp_object_equality وجسمها، والتي تحدد وظيفة ORDER التي تقارن سمة الراتب.
CREATE TYPE emp_object_equality AS OBJECT( salary NUMBER, ORDER MEMBER FUNCTION equals(c emp_object_equality)RETURN INTEGER); /
CREATE TYPE BODY emp_object_equality AS ORDER MEMBER FUNCTION equals(c emp_object_equality)RETURN INTEGER IS BEGIN IF salary<c.salary THEN RETURN -1; ELSIF salary>c.salary THEN RETURN 1; ELSE RETURN 0; END IF; END; END; /
Code التفسير:
- Code الأسطر 1-4: إنشاء نوع الكائن 'emp_object_equality' مع سمة واحدة وعضو واحد.
- Code الأسطر 6-16: تعريف دالة ORDER التي تقارن سمة "الراتب" في الكائن SELF مع الكائن المُعامل. تُرجع هذه الدالة قيمة سالبة إذا كان راتب الكائن SELF أقل، وقيمة موجبة إذا كان راتب الكائن SELF أكبر، وصفرًا إذا كان الراتبان متساويين.
Code الإخراج:
تم إنشاء النوع
الخطوة 2) إنشاء الكتلة المجهولة لمقارنة مثيلات الكائن.
تُظهر لقطة الشاشة أدناه الكتلة المجهولة التي تقارن بين مثيلين من emp_object_equality حسب الراتب.
DECLARE l_obj_1 emp_object_equality; l_obj_2 emp_object_equality; BEGIN l_obj_1:=emp_object_equality(15000); l_obj_2:=emp_object_equality(17000); IF l_obj_1.equals(l_obj_2)>0 THEN Dbms_output.put_line('Salary of first instance is greater'); ELSIF l_obj_1.equals(l_obj_2)<0 THEN Dbms_output.put_line('Salary of second instance is greater'); ELSE Dbms_output.put_line('Salaries are equal'); END IF; END; /
الناتج
Salary of second instance is greater
Code التفسير:
- Code السطر 20: إعلان 'l_obj_1' من النوع 'emp_object_equality'.
- Code السطر 21: إعلان 'l_obj_2' من النوع 'emp_object_equality'.
- Code السطر 23: تهيئة 'l_obj_1' بقيمة الراتب '15000'.
- Code السطر 24: تهيئة 'l_obj_2' بقيمة الراتب '17000'.
- Code الأسطر 25-33: طباعة الرسالة بناءً على الرقم الذي تم إرجاعه بواسطة دالة ORDER.



















