Oracle البرنامج التعليمي لـ PL/SQL Dynamic SQL: التنفيذ الفوري وDBMS_SQL
ما هو SQL الديناميكي؟
التفاعل SQL هي منهجية برمجة لإنشاء وتشغيل البيانات في وقت التشغيل. يتم استخدامه بشكل أساسي لكتابة البرامج ذات الأغراض العامة والمرنة حيث سيتم إنشاء عبارات SQL وتنفيذها في وقت التشغيل بناءً على المتطلبات.
طرق لكتابة SQL الديناميكية
يوفر PL/SQL طريقتين لكتابة SQL الديناميكي
- NDS - SQL الديناميكي الأصلي
- DBMS_SQL
NDS (SQL الديناميكي الأصلي) – تنفيذ فوري
إن لغة SQL الديناميكية الأصلية هي الطريقة الأسهل لكتابة لغة SQL الديناميكية. فهي تستخدم الأمر "EXECUTE IMMEDIATE" لإنشاء لغة SQL وتنفيذها في وقت التشغيل. ولكن لاستخدام هذه الطريقة، يجب معرفة نوع البيانات وعدد المتغيرات التي سيتم استخدامها في وقت التشغيل مسبقًا. كما أنها توفر أداءً أفضل وتعقيدًا أقل عند مقارنتها بـ DBMS_SQL.
بناء الجملة
EXECUTE IMMEDIATE(<SQL>) [INTO<variable>] [USING <bind_variable_value>]
- يُظهر بناء الجملة أعلاه أمر التنفيذ الفوري.
- يعتبر البند INTO اختياريًا ويستخدم فقط إذا كان SQL الديناميكي يحتوي على عبارة تحديد تقوم بجلب القيم. يجب أن يتطابق نوع المتغير مع نوع المتغير في عبارة التحديد.
- يعد استخدام البند اختياريًا ويستخدم فقط إذا كان SQL الديناميكي يحتوي على أي متغير ربط.
مثال 1: في هذا المثال، سنقوم بجلب البيانات من جدول emp لـ emp_no '1001' باستخدام عبارة NDS.
DECLARE
lv_sql VARCHAR2(500);
lv_emp_name VARCHAR2(50):
ln_emp_no NUMBER;
ln_salary NUMBER;
ln_manager NUMBER;
BEGIN
ly_sql:=;SELECT emp_name,emp_no,salary,manager FROM emp WHERE
emp_no=:empmo:;
EXECUTE IMMEDIATE lv_sql INTO lv_emp_name,ln_emp_no:ln_salary,ln_manager
USING 1001;
Dbms_output.put_line('Employee Name:‘||lv_emp_name);
Dbms_output.put_line('Employee Number:‘||ln_emp_no);
Dbms_output.put_line(‘Salary:'||ln_salaiy);
Dbms_output.put_line('Manager ID:‘||ln_manager);
END;
/
الناتج
Employee Name : XXX Employee Number: 1001 Salary: 15000 Manager ED: 1000
شرح الكود:
- سطر الكود 2-6:الإعلان عن المتغيرات.
- سطر الكود 8: تأطير SQL في وقت التشغيل. يحتوي SQL على متغير الربط حيث الشرط ':empno'.
- سطر الكود 9: تنفيذ نص SQL المؤطر (والذي يتم في سطر الكود 8) باستخدام أمر NDS "التنفيذ الفوري"
- يتم استخدام المتغيرات في جملة "INTO" (lv_emp_name، ln_emp_no، ln_salary، ln_manager) للاحتفاظ بالقيم التي تم جلبها من استعلام SQL (emp_name، emp_no، الرواتب، المدير)
- توفر عبارة "USING" القيم لمتغير الربط في استعلام SQL (:emp_no).
- سطر الكود 10-13: عرض القيم جلبها.
DBMS_SQL لـ Dynamic SQL
توفر PL/SQL حزمة DBMS_SQL التي تتيح لك العمل باستخدام SQL الديناميكي. تتضمن عملية إنشاء SQL الديناميكي وتنفيذه العملية التالية.
- فتح المؤشر: سيتم تنفيذ SQL الديناميكي بنفس طريقة تنفيذ ملف المؤشر. لذلك، من أجل تنفيذ عبارة SQL، يجب علينا فتح المؤشر.
- تحليل SQL: الخطوة التالية هي تحليل SQL الديناميكي. ستتحقق هذه العملية من بناء الجملة وتبقي الاستعلام جاهزًا للتنفيذ.
- ربط القيم المتغيرة: الخطوة التالية هي تعيين قيم لمتغيرات الربط إن وجدت.
- تعريف العمود: الخطوة التالية هي تحديد العمود باستخدام مواضعه النسبية في عبارة التحديد.
- نفذ - اعدم: الخطوة التالية هي تنفيذ الاستعلام الذي تم تحليله.
- جلب القيم: الخطوة التالية هي جلب القيم المنفذة.
- إغلاق المؤشر: بمجرد جلب النتائج، يجب إغلاق المؤشر.
مثال 1: في هذا المثال، سنقوم بجلب البيانات من جدول emp لـ emp_no '1001' باستخدام عبارة DBMS_SQL.
DECLARE lv_sql VARCHAR2(500); lv_emp_name VARCHAR2(50); ln_emp_no NUMBER; ln_salary NUMBER; ln_manager NUMBER; ln_cursor_id NUMBER; ln_rows_processed; BEGIN lv_sql:=‘SELECT emp_name,emp_no,salary,manager FROM emp WHERE emp_no=:empmo’; in_cursor_id:=DBMS_SQL.OPEN_CURSOR; DBMS_SQL.PARSE(ln_cursor_id,lv_sql,DBMS_SQL.NATIVE); DBMS_SQL.BIXD_VARLABLE(ln_cursor_id,:‘empno‘,1001); DBMS_SQL.DEFINE_COLUMN(ln_cursor_ici,1,ln_emp_name); DBMS_SQL.DEFINE_COLUMN(ln_cursor_id,2,ln_emp_no); DBMS_SQL .DEFINE_COLUMN(ln_cursor_id,3,ln_salary); DBMS_SQL .DEFINE_COLUMN(ln_cursor_id,4,ln_manager); ln_rows__processed:=DBMS_SQL.EXECUTE(ln_cursor_id);
LOOP
IF DBMS_SQL.FETCH_ROWS(ln_cursor_id)=0
THEN
EXIT;
ELSE
DBMS_SQL.COLUMN_VALUE(ln_cursor_id,1,lv_emp_name);
DBMS_SQL.COLUMN_VALUE(ln_cursor_id,2,ln_emp_no);
DBMS_SQL.COLUMN_VALUE(ln_cursor_id,3,In_salary);
DBMS_SQL.COLUMN_VALUE(ln_cursor_id,4,In_manager);
Dbms_output.put_line('Employee Name:‘||lv_emp_name);
Dbms_output.put_line('Employee Number:l‘||ln_emp_no);
Dbms_output.put_line(‘Salary:‘||ln_salary);
Dbms_output.put_line('Manager ID :‘| ln_manager);
END IF;
END LOOP;
DBMS_SQL.CLOSE_ClIRSOR(ln_cursor_id);
END:
/
الناتج
Employee Name:XXX Employee Number:1001 Salary:15000 Manager ID:1000
شرح الكود:
- سطر الكود 1-9: إعلان متغير.
- سطر الكود 10: تأطير بيان SQL.
- سطر الكود 11: فتح المؤشر باستخدام DBMS_SQL.OPEN_CURSOR. سيعود معرف المؤشر الذي تم فتحه.
- سطر الكود 12: بعد فتح المؤشر، يتم تحليل SQL.
- سطر الكود 13: يتم تعيين متغير الربط '1001' لمعرف المؤشر بدلاً من ':empno'.
- سطر الكود 14-17: تحديد اسم العمود بناءً على موضعه النسبي في عبارة SQL. في حالتنا، المنصب النسبي هو (1) emp_name، (2) emp_no (3) الراتب (4) مدير. لذا بناءً على هذا الموضع، فإننا نحدد المتغير المستهدف.
- سطر الكود 18: تنفيذ الاستعلام باستخدام DBMS_SQL.EXECUTE. تقوم بإرجاع عدد السجلات التي تمت معالجتها.
- سطر الكود 19-33: جلب السجلات باستخدام حلقة وعرضها.
- سطر الكود 20: سيقوم DBMS_SQL.FETCH_ROWS بإحضار سجل واحد من الصفوف التي تمت معالجتها. يمكن استدعاؤه بشكل متكرر لجلب كافة الصفوف. إذا لم يتمكن من جلب الصفوف، فإنه سيعود 0، وبالتالي الخروج من الحلقة.
ملخص
في هذا القسم، ناقشنا SQL الديناميكي وطرق تنفيذ DYNAMIC SQL. لقد رأينا أيضًا الخطوات المختلفة لتنفيذ SQL الديناميكي في كلا الطريقتين. لقد رأينا أيضًا الأمثلة التي يتم فيها التعامل مع نفس السيناريو بطريقتي NDS وDBMS_SQL لتنفيذ التنفيذ في وقت التشغيل.



