محاضرة ASP 8: ASP وقاعدة البيانات (3)
الكاتب:Eve Cole
وقت التحديث:2009-05-30 19:55:00
في المحاضرتين الأخيرتين، قمنا بشرح الاستخدام الأساسي لقواعد البيانات في لغة ASP. واليوم سنقدم العديد من التقنيات العملية للغاية.
1. تقنية الترحيل لقد قدمنا كيفية استرداد البيانات وإخراجها إلى المتصفح، بالنسبة لكمية صغيرة من البيانات، تكون معالجة الإخراج البسيطة هذه مقبولة تمامًا، ومع ذلك، إذا كانت كمية البيانات كبيرة، مع مئات أو حتى آلاف العناصر ، من غير الواقعي إخراج الكثير من البيانات إلى العميل في وقت واحد. أولاً، تمتد الصفحة لفترة طويلة جدًا من الأعلى إلى الأسفل. ثانيًا، ينتظر العميل وقتًا طويلاً. ثالثًا، يكون الحمل على الخادم ثقيلًا جدًا. ولذلك فمن الضروري جدا أن تأخذ الإخراج المقسم إلى صفحات.
المتطلبات: قم بإخراج البيانات الموجودة في جدول "المنتج" الخاص بـ Northwind.mdb إلى المستعرض، وعرض 10 عناصر في كل صفحة.
خذ wuf60.asp كمثال. لا يزال هذا الرمز صعبًا بعض الشيء. لقد تم ذكر AdoAccess.asp في المحاضرة.
ملحوظة: يتضمن هذا الروتين أجزاء جيدة من بعض الكتب، وهذا ما يعلن عنه.
<%@ LANGUAGE="VBSCRIPT" %>
<!--#include file="AdoAccess.asp"-->
<!--#include file="adovbs.inc"-->
<%
خافت RecordPerPage، absPageNum، TotalPages، absRecordNum، rsTest، StrSQL
'absPageNum - ما هي الصفحة الحالية؟
'TotalPages - إجمالي عدد الصفحات
'absRecordNum - الرقم التسلسلي للسجل في الصفحة الحالية، مثل 1-10
RecordPerPage = 10 'عدد السجلات المعروضة في كل صفحة
'احصل على رقم الصفحة الحالية لبيانات الإخراج
إذا كانت Request.ServerVariables("CONTENT_LENGTH") = 0 إذن
'إذا لم يتم استلام البيانات المقدمة بواسطة النموذج (مثلاً عند تحميل الصفحة لأول مرة)، فسيتم عرضها من الصفحة 1
رقم الصفحة = 1
آخر
'احصل على رقم الصفحة عند الضغط على الزر
absPageNum = CInt(Request.Form("PressPageNum"))
'إذا ضغطت على الصفحة السابقة، يكون رقم الصفحة هو -1، وإذا ضغطت على الصفحة التالية، يكون رقم الصفحة +1
إذا Request.Form("Submit") = "الصفحة السابقة" إذن
absPageNum = absPageNum - 1
ElseIf Request.Form("Submit") = "الصفحة التالية" إذن
absPageNum = absPageNum + 1
نهاية إذا
نهاية إذا
'إنشاء كائن مجموعة السجلات
تعيين rsTest = Server.CreateObject("ADODB.Recordset")
rsTest.CursorLocation = adUseClient 'يمكن أن يؤدي هذا الإعداد إلى تقليل تحميل قاعدة البيانات
rsTest.CursorType = adOpenStatic 'يحتاج المؤشر إلى التحرك للأمام والخلف ولا يمكن ضبطه على الأمام فقط
rsTest.CacheSize = RecordPerPage 'سيؤدي تعيين هذا الخيار إلى تحسين الأداء
StrSQL = "حدد * من طلب المنتج حسب معرف المنتج"
rsTest.Open StrSQL، Cnn،،، adCmdText
rsTest.PageSize = RecordPerPage 'قم بتعيين عدد السجلات لكل صفحة
إذا لم يكن (rsTest.EOF) ثم
rsTest.AbsolutePage = absPageNum
نهاية إذا
TotalPages = rsTest.PageCount
%>
<% 'يقوم الجزء التالي بإخراج بيانات الصفحة الحالية إلى المتصفح%>
<أتش تي أم أل><بوبي>
<جدول colspan=8 cellpadding=5 حدود=0>
<تر>
<td align=CENTER bgcolor="#800000" width="109"> <font style="ARIAL NARROW" color="#ffffff" size="2">سعر الوحدة</font></td>
<td align=CENTER width=459 bgcolor="#800000"> <font style="ARIAL NARROW" color="#ffffff" size="2">اسم المنتج</font></td>
</tr>
<% 'استخدم حلقة لإخراج 10 أجزاء من البيانات في الصفحة الحالية
بالنسبة لـ absRecordNum = 1 إلى rsTest.PageSize
%>
<تر>
<td bgcolor="f7efde" align=CENTER> <font style="ARIAL NARROW" size="2"><%= rsTest("سعر الوحدة")%></font></td>
<td bgcolor="f7efde" align=CENTER> <font style="ARIAL NARROW" size="2"><%= rsTest("اسم المنتج")%></font></td>
</tr>
<%
rsTest.MoveNext
إذا rsTest.EOF ثم
Exit For ' إذا تم الوصول إلى نهاية السجل، قم بالخروج - إذا لم تكن الصفحة الأخيرة من البيانات ممتلئة.
نهاية إذا
التالي
rsTest.Close: Cnn.Close
تعيين rsTest = لا شيء: تعيين Cnn = لا شيء
%>
</الجدول>
<% 'الجزء السفلي عبارة عن زرين "الصفحة السابقة" "الصفحة التالية" %>
<إجراء النموذج = "<%= Request.ServerVariables("SCRIPT_NAME") %>" Method="Post">
<نوع الإدخال = "مخفي" الاسم = "قيمة PressPageNum" = "<%= absPageNum%>">
<%
إذا كانت absPageNum > 1 ثم "إذا لم تكن الصفحة الحالية هي الصفحة الأولى، فاعرض زر الصفحة السابقة%>
<نوع الإدخال = "إرسال" الاسم = "إرسال" القيمة = "الصفحة السابقة">
<% نهاية إذا
إذا كانت absPageNum <> TotalPages، فعندئذٍ "إذا لم تكن الصفحة الحالية هي الصفحة الأخيرة، فاعرض زر الصفحة التالية%>
<نوع الإدخال = "إرسال" الاسم = "إرسال" القيمة = "الصفحة التالية">
<% نهاية إذا %>
</النموذج>
<P><Center> [الصفحة<font color="#CC0033"><%= absPageNum %></font>،
إجمالي<font color="#CC0033"><%= إجمالي الصفحات %></font> الصفحات] </Center></P>
</BODY></HTML>
تحليل:
1. بعض الخصائص المفيدة لكائن Recordset:
l rsTest.CursorLocation = adUseClient: يمكنك أيضًا حذف هذه الجملة، لكن القيام بذلك قد يقلل من تحميل قاعدة البيانات؛
l rsTest.CacheSize = RecordPerPage: يتم استخدام سمة CacheSize لتحديد مقدار البيانات التي يحصل عليها العميل من خادم قاعدة البيانات في كل مرة؛
l rsTest.PageSize: يتم استخدام سمة PageSize لتعيين عدد السجلات في كل صفحة؛
l rsTest.AbsolutePage: تقوم خاصيةAbsolutePage بتعيين العدد المطلق لصفحات البيانات الحالية في كائن Recordset؛
l rsTest.PageCount: يتم استخدام خاصية PageCount للحصول على إجمالي عدد الصفحات في مجموعة السجلات.
2. يستخدم هذا النموذج حقلاً مخفيًا PressPageNum لتمرير الصفحة عند النقر فوق الزر.
2. معالجة الأخطاء أثناء تنفيذ التعليمات البرمجية، قد تحدث أخطاء لأسباب مختلفة، مثل: مشاكل في التعليمات البرمجية نفسها، وانقطاع الاتصال بالشبكة، وما إلى ذلك، لذلك من الضروري جدًا إعداد التقاط الأخطاء ومعالجتها في البرنامج. في ASP، يمكننا الحصول على معلومات الخطأ أو التحذير التي تحدث عند تشغيل التعليمات البرمجية من خلال مجموعة بيانات الأخطاء لكائن الاتصال.
1. استخدمه مباشرة على كائن الاتصال:
تعيين الأخطاء = Cnn.Errors
أو
سي إن إن. أخطاء
2. بعد إنشاء كائن Recordset أو كائن Command، استخدم كائن Connection من خلال خاصية ActiveConnection الخاصة به:
تعيين الأخطاء = rsTest.ActiveConnection.Errors
أو
rsTest.ActiveConnection.Errors
قد يبدو الأمر فظًا للغاية، لذلك دعونا نعطي مثالاً: wuf61.asp
<%@ LANGUAGE="VBSCRIPT" %>
<% خيار صريح %>
<!--#include file="adovbs.inc"-->
<%
الاستجابة.انتهاء الصلاحية = 0
'تضمن الجملة التالية: حتى لو واجه البرنامج النصي خطأ، فإنه سيستمر في تنفيذ الجملة التالية
على خطأ استئناف التالي
ديم سي إن إن، رستيست، إرس، آي
تعيين Cnn = Server.CreateObject("ADODB.Connection")
'CommandTimeout - الحد الأقصى لوقت الانتظار للاتصال بقاعدة البيانات، الافتراضي هو 15 ثانية
Cnn.CommandTimeout = 5
'يمكنك اكتشاف الأخطاء في المواقف الثلاثة التالية - مع أخذ SQL Server كمثال
'1 - صحيح تمامًا؛ 2 - لم يتم تعيين قاعدة البيانات الأولية؛ 3 - اسم قاعدة البيانات pvbs بشكل خاطئ
Cnn.Open "الموفر=sqloledb; معرف المستخدم=sa; كلمة المرور=; الكتالوج الأولي=الناشرون; مصدر البيانات=ICBCZJP"
'Cnn.Open "Provider=sqloledb; معرف المستخدم=sa; كلمة المرور=; الكتالوج الأولي=; مصدر البيانات=ICBCZJP"
'Cnn.Open "Provider=sqloledb; معرف المستخدم=sa; كلمة المرور=; الكتالوج الأولي=pvbs; مصدر البيانات=ICBCZJP"
لأني = 0 إلى Cnn.Errors.Count - 1
'تشير سمة المصدر إلى مصدر الخطأ
الاستجابة.اكتب "[ " & Cnn.Errors(I).المصدر & " ] "
'تشير سمة الوصف إلى سبب الخطأ أو وصفه
الاستجابة.اكتب Cnn.Errors(I).الوصف و"<br>"
التالي
إذا كان Cnn.Errors.Count> 0 ثم
الاستجابة.اكتب "حدث أثناء الاتصال" & Cnn.Errors.Count & "الأخطاء" & "<br>"
نهاية إذا
تعيين rsTest = Server.CreateObject("ADODB.Recordset")
rsTest.Open "وظائف"، CNN، adOpenForwardOnly، adLockReadOnly، adCmdTable
إذا كان rsTest.ActiveConnection.Errors.Count > 0 ثم
تعيين جلسة ("Errs") = rsTest.ActiveConnection.Errors
الاستجابة.إعادة توجيه "ErrorHandle.asp"
نهاية إذا
سي إن إن. إغلاق
تعيين rsTest = لا شيء: تعيين Cnn = لا شيء
%>
كود ErrorHandle.asp:
<%
خافت أنا
لأنني = 0 إلى الجلسة ("الأخطاء").العدد - 1
الاستجابة.اكتب "[ " & الجلسة("Errs")(I).المصدر & " ] "
الاستجابة.كتابة الجلسة("Errs")(I).الوصف و"<br>"
التالي
%>
تحليل:
في هذه الحالة، ربما حدث الخطأ أثناء الاتصال، أو ربما كان الاتصال صحيحًا، ولكن حدث خطأ أثناء استخدام كائن Recordset.
بالإضافة إلى ذلك، في الجزء التالي من التعليمات البرمجية، يتم وضع مجموعة الأخطاء في كائن جلسة بحيث يمكن استدعاؤها بين الصفحات (عند مواجهة خطأ، انتقل إلى صفحة معالجة الأخطاء ErrorHandle.asp).
في الواقع، يمكنك أيضًا تعيين كائن مجموعة السجلات إلى كائن الجلسة لتنفيذ استدعاء مجموعة السجلات بين الصفحات.
3. مفهوم استخدام المعاملات بسيط ومهم للغاية، ولتوضيح استخدامه، دعونا نفترض أولاً الموقف التالي: على سبيل المثال، في التجارة الإلكترونية، عند إجراء تحويلات العملة عبر الإنترنت، يجب طرح مبلغ معين من مبلغ ما. المبلغ وإضافة المبلغ المعادل له إلى حساب آخر. ومهما فشل أي من التحديثات، فإنه سيؤدي إلى خلل في رصيد الحساب (إما أن يكون هناك خصم هنا ولكن لا يوجد زيادة هناك؛ أو لا يوجد خصم هنا ولكن هناك زيادة هناك) . إذا كنت تستخدم معاملة لإجراء هذه التغييرات، فإنك تتأكد من أنه يمكنك فقط اختيار إجراء جميع التغييرات أو عدم إجراء أي تغييرات (إما صحيحة تمامًا أو ملغاة تمامًا).
تنتمي المعاملات إلى كائن الاتصال، الذي يحتوي على ثلاث طرق متعلقة بالمعاملات:
ل يبدأ BeginTrans معاملة جديدة.
l يحفظ CommitTrans جميع التغييرات وينهي المعاملة الحالية.
l يقوم RollbackTrans بإلغاء أي تغييرات تم إجراؤها في المعاملة الحالية وإنهاء المعاملة، والتي تسمى غالبًا "التراجع".
قد ننظر أيضًا إلى مثال wuf62.asp.
<%@ LANGUAGE="VBSCRIPT" %>
<% خيار صريح %>
<!--#include file="adovbs.inc"-->
<%
الاستجابة.انتهاء الصلاحية = 0
على خطأ استئناف التالي
DimCnn، StrSQL، rsTest
تعيين Cnn = Server.CreateObject("ADODB.Connection")
Cnn.Open "الموفر=sqloledb; معرف المستخدم=sa; كلمة المرور=; الكتالوج الأولي=الناشرون; مصدر البيانات=ICBCZJP"
'ابدأ الصفقة
سي إن إن بيجين ترانس
StrSQL = "أدخل الوظائف(job_desc, min_lvl, max_lvl) القيم('Finance',16,86)"
Cnn. تنفيذ StrSQL
"الجملة الأولى أدناه خاطئة، والجملة الثانية صحيحة
StrSQL = "تحديث jobs_err SET job_desc = 'المعاملة' حيث job_id = 14"
'StrSQL = "تحديث الوظائف SET job_desc = 'المعاملة' حيث job_id = 14"
Cnn. تنفيذ StrSQL
إذا كان Cnn.Errors.Count> 0 ثم
Response.Write "حدث خطأ، يقوم النظام باستعادة الحالة في بداية المعاملة، ولن يتم إجراء أي إضافات أو تعديلات جديدة" & "<br>"
Cnn.RollbackTrans
آخر
Response.Write "لا توجد أخطاء، احفظ التغييرات في قاعدة البيانات، أضف جزءًا جديدًا من البيانات، قم بتعديل جزء من البيانات" و"<br>"
Cnn.CommitTrans
نهاية إذا
تعيين rsTest = Cnn.Execute("اختر * من الوظائف حيث job_id>=14")
بينما ليس rsTest.EOF
الاستجابة.اكتب rstest(0) وrstest(1) وrstest(2) وrstest(3) و"<br>"
rsTest.MoveNext
ويند
'هذا المثال للاختبار فقط، لذا قم باستعادة البيانات الأصلية لقاعدة البيانات
Cnn.Execute "تحديث المهام SET job_desc = 'المصمم' حيث job_id = 14"
Cnn.تنفيذ "حذف الوظائف حيث job_id > 14"
Cnn.Close: تعيين Cnn = لا شيء
%>
في هذا المثال، إما أن يحدث الإدراج والتحديث في نفس الوقت أو لن يحدث أي منهما. يعد استخدام المعاملات عادة جيدة جدًا عند برمجة قواعد البيانات.
4. معالجة مجموعات سجلات متعددة نحتاج أحيانًا إلى الحصول على بيانات من جدولين في نفس الوقت، إذا تم إرجاعها في عبارة SQL واحدة، فيمكن تقليل نقل الشبكة وتحسين كفاءة التشغيل.
خذ wuf64.asp كمثال. يشرح هذا المثال أيضًا كيفية استخدام حلقة لإخراج قيم الحقول (في الماضي، استخدمنا طرقًا غبية مثل "rsTest(0) & rsTest(1) &..." للإخراج. إذا كان هناك حقلان أو ثلاثة حقول فقط، فمن الواضح أن هذه الطريقة أكثر إيجازًا)، وإذا لم تتمكن من فهمها في الوقت الحالي، فيرجى تنزيل wuf63.asp الأبسط، وتذكر! .
<%@ LANGUAGE="VBSCRIPT" %>
<%
الخيار صريح
الاستجابة.انتهاء الصلاحية = 0
خافت Cnn، StrSQL، rsTest، I
تعيين Cnn = Server.CreateObject("ADODB.Connection")
Cnn.Open "الموفر=sqloledb; معرف المستخدم=sa; كلمة المرور=; الكتالوج الأولي=الناشرون; مصدر البيانات=ICBCZJP"
تعيين rsTest = Server.CreateObject("ADODB.Recordset")
'استرداد مجموعات سجلات متعددة
StrSQL = "اختر COUNT(*) AS 'عدد الموظفين' من الموظف؛ حدد * من الوظائف"
rsTest.Open StrSQL، Cnn،،،،adCmdText
في حين أن ليس rsTest لا شيء
Response.Write "<حدود الجدول = 2><tr>"
'rsTest.Fields.Count - عدد الحقول في مجموعة السجلات
لأني = 0 إلى rsTest.Fields.Count - 1
'rsTest(I).Name - اسم الحقل للحقل I
الاستجابة.اكتب "<td>" & rsTest(I).الاسم & "</td>"
التالي
الاستجابة.اكتب "</tr>"
بينما ليس rsTest.EOF
الاستجابة.اكتب "<tr>"
'استخدم حلقة لإخراج قيمة كل حقل
لأني = 0 إلى rsTest.Fields.Count - 1
الاستجابة.اكتب "<td>" وrsTest(I) و"</td>"
التالي
الاستجابة.اكتب "</tr>"
rsTest.MoveNext
ويند
'اقرأ كائن Recordset التالي
تعيين rsTest = rsTest.NextRecordset
ويند
سي إن إن. إغلاق
تعيين rsTest = لا شيء: تعيين Cnn = لا شيء
%>
ملاحظة: تدعم قاعدة بيانات SQL Server مجموعات سجلات متعددة، لكن قاعدة بيانات Access لا تدعم ذلك.
5. قم بإغلاق الاتصال في أقرب وقت ممكن لتحرير الموارد
في الأمثلة السابقة، تم إغلاق الاتصال أخيرًا، ومع ذلك، يستهلك كائن الاتصال الموارد، وفي الواقع، وفقًا للطريقة التي يوفرها wuf65.asp أدناه، يمكن إغلاق الاتصال مسبقًا.
<% @LANGUAGE = VBScript %>
<!--#include file="AdoAccess.asp"-->
<!--#include file="adovbs.inc"-->
<%' wuf65.asp
خافت StrSQL، rsTest
StrSQL = "اختر * من الشاحن"
تعيين rsTest = server.CreateObject("ADODB.Recordset")
'يجب عليك استخدام مؤشر العميل، وإلا فلن يعمل
rsTest.CursorLocation = adUseClient
rsTest.Open StrSQL،Cnn،،،adCmdText
'قم بإزالة اعتماد مجموعة السجلات على كائن الاتصال
تعيين rsTest.ActiveConnection = لا شيء
"أغلق الاتصال في أقرب وقت ممكن."
Cnn.إغلاق: تعيين Cnn = لا شيء
افعل بينما لا rsTest.EOF
الاستجابة.اكتب rsTest(0) & " " & rsTest(1) & " " & rsTest(2) & " " & "<BR>"
rsTest.MoveNext
حلقة
تعيين rsTest = لا شيء
%>