كثيرة هي الحالات التي تحتاج فيها الى استخدام اجراء مخزن Stored Procedure للاضافة و التحديث بينما تستعمل استعلام مباشر لاظهار البيانات.
مثال:
الاستظهار:
اظهار رقم الطالب,اسمه, و عنوانه عن طريق استعلام مباشر:
ٍSelect Id,Name,Address From Students
تعديل طالب جديد عن طريق اجراء مخزن :الاجراء سييستقبل مدخلين هما رقم الطالب و عنوانه (بينما اسم الطالب فموجود مسبقا و لا يمكن تعديله )
المشكلة انه عندما تعمل run للSqlDataSource التي تنادي الاجراء المخزن المسؤول عن التعديل فانك تحصل على رسالة خطأ مشابهة ل:
Too many arguments specified
(انا استخدم اوراكل في قاعدة البيانات,لكن حتى بالنسبة لsql server فانك ستحصل على رسالة مشابهة)
السبب هو ان وجود اي عنصر في الGridView او FormView او DetailsView مربوط بقاعدة البيانات عن طريق الخاصية Bind فان الحقل المربوط بالعنصر و قيمته سيتم التعامل معه كمدخلات ترسل الى الاجراء المخزن .فلو افترضنا انك تريد تعديل سجل طالب و ارسلت قيمة رقم الطالب و عنوانه بينما كان لديك العنصر الذي يظهر اسم الطالب كالتالي:
<asp:Label ID="Label1" runat="server" Text='<%# Bind("Name") %>'></asp:Label>فان الصفحة ستقوم بارسال مدخل جديد (لا تحتاجه و لم تكن تتوقعه) الى الاجراء المخزن و بالتالي يصبح عدد المدخلات parameter هو 3 (اي 2 تحتاجهما وهما رقم الطالب و عنوانه بينما المدخل الثالث والذي لم تتوقعه فهو الاتي من العنصر Label1 و يحتوي اسم الطالب)
هنك حالة اخرى و هو انه بمجرد تعيينك للخاصية DataKeyNames في الGridView فان قيمة المفتاح سترسل كمدخل اضافي للاجراء المخزن و بالتالي سيحدث الخطأ المشار اليه اعلاه.
الحل:
هو ان تحذف كل المدخلات parameters التي ترسلها الصفحة ما لم تكن موجودة في قائمة مدخلات الاضافة (او التعديل ,حسب الحالة) و نقوم بعمل ذلك في الحدث Updating الخاص بال
SqlDataSource
protected void UpdateStudentDataSource_Updating(object sender, SqlDataSourceCommandEventArgs e)
{
for (int i = e.Command.Parameters.Count - 1; i >= 0; i--)
if(UpdateStudentDataSource.UpdateParameters[e.Command.Parameters.ParameterName] == null)
e.Command.Parameters.RemoveAt(e.Command.Parameters.ParameterName);
}