Oracle مجموعة PL/SQL المجمعة: مثال شامل
⚡ ملخص ذكي
خدمة التجميع بالجملة في Oracle تسترجع لغة PL/SQL العديد من الصفوف دفعة واحدة إلى مجموعة، بينما تقوم عبارة FORALL بإعادة تنفيذ عمليات DML بكميات كبيرة إلى قاعدة البيانات. يقلل كلا الأسلوبين من عمليات تبديل السياق بين محركي SQL وPL/SQL، مما يحسن الأداء.
ما هو الجمع بالجملة؟
يقلل التجميع المجمع من عمليات تبديل السياق بين SQL ومحرك PL/SQL ويسمح لمحرك SQL بجلب السجلات دفعة واحدة.
Oracle PL / SQL تُتيح هذه الخاصية جلب السجلات دفعةً واحدة بدلاً من جلبها واحدًا تلو الآخر. ويمكن استخدام BULK COLLECT في عبارة SELECT لتعبئة السجلات دفعةً واحدة، أو لجلبها بشكل فردي. المؤشر بشكل مجمع. بما أن BULK COLLECT يجلب السجلات دفعة واحدة، يجب أن تحتوي عبارة INTO دائمًا على متغير من نوع مجموعة. الميزة الرئيسية لاستخدام BULK COLLECT هي أنها تزيد الأداء عن طريق تقليل التفاعل بين قاعدة البيانات ومحرك PL/SQL.
بناء الجملة:
SELECT <column1> BULK COLLECT INTO bulk_variable FROM <table name>; FETCH <cursor_name> BULK COLLECT INTO <bulk_variable>;
في الصيغة المذكورة أعلاه، يتم استخدام BULK COLLECT لجمع البيانات من عبارات SELECT و FETCH.
البند FORALL
تؤدي عبارة FORALL وظيفة عمليات DML تُعالج البيانات بكميات كبيرة. وهي تُشبه حلقة FOR، إلا أن العمليات في حلقة FOR تُنفذ على مستوى السجل، بينما لا يوجد مفهوم حلقة في FORALL. بدلاً من ذلك، تُعالج جميع البيانات الموجودة في النطاق المحدد في نفس الوقت.
بناء الجملة:
FORALL <loop_variable> in <lower range> .. <higher range>
<DML operations>;
في الصيغة المذكورة أعلاه، سيتم تنفيذ عملية DML المعطاة لجميع البيانات الموجودة بين النطاق الأدنى والنطاق الأعلى.
بند الحد
تعتمد تقنية التجميع المجمّع على تحميل جميع البيانات دفعةً واحدة إلى متغير المجموعة المستهدف، أي يتم ملء جميع البيانات في متغير المجموعة في عملية واحدة. إلا أن هذه التقنية غير مستحسنة عندما يكون إجمالي عدد السجلات المطلوب تحميلها كبيرًا جدًا، لأن محاولة PL/SQL تحميل جميع البيانات تستهلك قدرًا كبيرًا من ذاكرة الجلسة. لذا، يُنصح دائمًا بتقييد حجم عملية التجميع المجمّع هذه.
يمكن تحقيق حد الحجم هذا بسهولة عن طريق إدخال شرط ROWNUM في عبارة SELECT، بينما في حالة المؤشر، لا يكون ذلك ممكناً.
للتغلب على هذا ، Oracle وقد تم توفير بند LIMIT الذي يحدد عدد السجلات التي يجب تضمينها في المجموعة.
بناء الجملة:
FETCH <cursor_name> BULK COLLECT INTO <bulk_variable> LIMIT <size>;
في الصيغة المذكورة أعلاه، تستخدم عبارة جلب المؤشر عبارة BULK COLLECT مع عبارة LIMIT.
سمات التجميع المجمعة
على غرار خصائص المؤشر، تحتوي دالة BULK COLLECT على %BULK_ROWCOUNT(n) التي تُعيد عدد الصفوف المتأثرة في عبارة DML رقم n من عبارة FORALL، أي أنها تُعطي عدد السجلات المتأثرة في عبارة FORALL لكل قيمة من متغير المجموعة. يشير الرقم 'n' إلى تسلسل القيمة في المجموعة التي يلزم حساب عدد صفوفها.
مثال 1: في هذا المثال، سنقوم بعرض جميع أسماء الموظفين من جدول الموظفين باستخدام BULK COLLECT، وسنقوم أيضًا بزيادة رواتب جميع الموظفين بمقدار 5000 باستخدام FORALL.
تُظهر لقطة الشاشة أدناه مثال BULK COLLECT و FORALL هذا بالإضافة إلى مخرجاته في Oracle.
DECLARE CURSOR guru99_det IS SELECT emp_name FROM emp; TYPE lv_emp_name_tbl IS TABLE OF VARCHAR2(50); lv_emp_name lv_emp_name_tbl; BEGIN OPEN guru99_det; FETCH guru99_det BULK COLLECT INTO lv_emp_name LIMIT 5000; FOR c_emp_name IN lv_emp_name.FIRST .. lv_emp_name.LAST LOOP Dbms_output.put_line('Employee Fetched:'||c_emp_name); END LOOP; FORALL i IN lv_emp_name.FIRST .. lv_emp_name.LAST UPDATE emp SET salary=salary+5000 WHERE emp_name=lv_emp_name(i); COMMIT; Dbms_output.put_line('Salary Updated'); CLOSE guru99_det; END; /
الناتج
Employee Fetched:BBB Employee Fetched:XXX Employee Fetched:YYY Salary Updated
Code التفسير:
- Code السطر 2: تعريف المؤشر guru99_det للعبارة 'SELECT emp_name FROM emp'.
- Code السطر 3: تم تعريف lv_emp_name_tbl كنوع جدول من VARCHAR2(50).
- Code السطر 4: تعريف lv_emp_name كنوع lv_emp_name_tbl.
- Code السطر 6: فتح المؤشر.
- Code السطر 7: جلب المؤشر باستخدام BULK COLLECT مع حجم LIMIT 5000 إلى متغير lv_emp_name.
- Code الأسطر 8-11: إعداد حلقة FOR لطباعة جميع السجلات في المجموعة lv_emp_name.
- Code السطر 12: استخدام FORALL لتحديث رواتب جميع الموظفين بمقدار 5000.
- Code السطر 14: الالتزام بـ صفقة.


