• 0
alroaini100

مشكلة التعامل مع اكثر من سجل

سؤال

السلام عليكم ورحمة منه وبركاته

مشكلتي هي ان الكود التالي لا ينطبق علي اكثر من سجل وانما يعمل علي سجل واحد 

ياليت تساعدوني بحل الله يجزيكم كل خير 

DECLARE @MothersId intset @MothersId=1036DECLARE @dateofbirth datetimeDECLARE @currentdatetime DATETIMEDECLARE @years VARCHAR(40)DECLARE @months VARCHAR(30)DECLARE @days VARCHAR(30)DECLARE @SonId int DECLARE @SonYatem int=0DECLARE @SonMoal int=0DECLARE @SonStudyMoal int=0SET @years=(select datediff(year, DateBirth, GETDATE()) from Deceased_Sons where [email protected])--birthdateSET @months=(select datediff(month, DateBirth, GETDATE()) - (datediff(year, DateBirth, GETDATE()) * 12) from Deceased_Sons where [email protected]) set @days=(select datepart(d, GETDATE()) - datepart(d, DateBirth)from Deceased_Sons where [email protected] )if @years<=18 set @SonYatem=+1if @years>18 and @years<=20set @SonMoal=+1if @years>20 and @years<=22set @SonStudyMoal=+1select @SonYatem,@SonMoal,@SonStudyMoal
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

6 إجابة على هذا السؤال .

  • 0

السلام عليكم و رحمة الله و بركاته

 

اخي الكريم عدة حلول و سأقترح عليك بعضا منها:

 

 

1- أن تنشئ إجراء مخزن يحتوي على مؤشر يمر على كل السجلات المطلوب تطبيق السكريبت خاصتك عليها (راجع درس المؤشرات خاصتي للتعرف على كيفية  استخدامها).

 

2- أو تجلب السجلات الى البرنامج الهدف عن طريق SqlDataReader أو SqlDataAdapter أقصد الـ ADO.NET و تنشئ حلقة تمر بها على كل سجل و تستدعي من أجله اجراء مخزن يطبق ما تريد على كل سجل على حدى.

 

3- باستخدام الـ LINQ To SQL أو الـ Entity Framework لتجلب الـ Records الهدف على شكل ObjectSet و تنشئ حلقة ايضا لتمر على السجلات و تطبق السكريبت خاصتك الذي يجب أن يكون اجراء مخزن تستدعيه في كل مرور للحلقة.

 

بالتوفيق

تم تعديل بواسطه imadouzoun
1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

وعليكم السلام ورحمة الله وبركاته 

اخي الكريم جزاك الله الف الف خير وبارك الله  فيك 

بالنسبه للحلول انا جربت الحل الثالث  تمام 100% 

لكن  اريد افعل  اجراء مخزن من اجل استخدمه مباشره في التقارير 

 باحاول اقراء دروسك في المؤشرات  واعطيك النتيجه

تم تعديل بواسطه alroaini100
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

السلام عليكم و رحمة الله و بركاته

 

اخي الكريم عدة حلول و سأقترح عليك بعضا منها:

 

 

1- أن تنشئ إجراء مخزن يحتوي على مؤشر يمر على كل السجلات المطلوب تطبيق السكريبت خاصتك عليها (راجع درس المؤشرات خاصتي للتعرف على كيفية  استخدامها).

 

2- أو تجلب السجلات الى البرنامج الهدف عن طريق SqlDataReader أو SqlDataAdapter أقصد الـ ADO.NET و تنشئ حلقة تمر بها على كل سجل و تستدعي من أجله اجراء مخزن يطبق ما تريد على كل سجل على حدى.

 

3- باستخدام الـ LINQ To SQL أو الـ Entity Framework لتجلب الـ Records الهدف على شكل ObjectSet و تنشئ حلقة ايضا لتمر على السجلات و تطبق السكريبت خاصتك الذي يجب أن يكون اجراء مخزن تستدعيه في كل مرور للحلقة.

 

بالتوفيق

 

الاخ العزيز 

جميع الحلول التى طرحتها جيدة و لكن ليست عملية للاسباب التالية :-

1- استخدام المؤشرات لن يحقق المطلوب اذا كان تنفيذ عملية الاستعلام سيتم من خلال برنامج تطبيقي حيث ان طريقة المؤشرات تستخدم من خلال ( T SQL ) فقط .

2- جلب السجلات الى البرنامج الهدف و الدخول فى حلقة تكرارية هى ايضا فكرة جيدة و لكنها سوف تاخذ وقتا طويلا جدا فى التنفيذ و خاصة اذا كان حجم البيانات كبير .. تخيل انك ستدخل فى حلقة بها 10000 سجل كم من الوقت سياخذ هذا الاستعلام !!

3- الفكرة الثالثة لا تختلف عن الفكرة الثانية حيث انه سيتوجب عليك ايضا الدخول فى حلقة تكرارية للمرور على جميع السجلات و بالتالى فهى ايضا فكرة غير مجدية .

 

والان السؤال ما هو الحل المثالى لهذه المشكلة ؟

الاجابة ... تغيير تركيبة الاستعلام نفسها و استخدام الدوال الاجرائية بدلا من استخدام جملة Set حيث ان الدوال الاجرائية يمكنها ان تعود بالقيم المختلفة للسجلات المطلوبة على حسب برمجة الدالة و هى حل أمثل بدلا من اسناد القيمة الى جملة Set التى تعود بقيمة واحدة فقط لسجل واحد .

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

الاخ العزيز 

جميع الحلول التى طرحتها جيدة و لكن ليست عملية للاسباب التالية :-

1- استخدام المؤشرات لن يحقق المطلوب اذا كان تنفيذ عملية الاستعلام سيتم من خلال برنامج تطبيقي حيث ان طريقة المؤشرات تستخدم من خلال ( T SQL ) فقط .

2- جلب السجلات الى البرنامج الهدف و الدخول فى حلقة تكرارية هى ايضا فكرة جيدة و لكنها سوف تاخذ وقتا طويلا جدا فى التنفيذ و خاصة اذا كان حجم البيانات كبير .. تخيل انك ستدخل فى حلقة بها 10000 سجل كم من الوقت سياخذ هذا الاستعلام !!

3- الفكرة الثالثة لا تختلف عن الفكرة الثانية حيث انه سيتوجب عليك ايضا الدخول فى حلقة تكرارية للمرور على جميع السجلات و بالتالى فهى ايضا فكرة غير مجدية .

 

والان السؤال ما هو الحل المثالى لهذه المشكلة ؟

الاجابة ... تغيير تركيبة الاستعلام نفسها و استخدام الدوال الاجرائية بدلا من استخدام جملة Set حيث ان الدوال الاجرائية يمكنها ان تعود بالقيم المختلفة للسجلات المطلوبة على حسب برمجة الدالة و هى حل أمثل بدلا من اسناد القيمة الى جملة Set التى تعود بقيمة واحدة فقط لسجل واحد .

 

تعقيب على البند الأول: اعذرني فالكلام الذي قلته غير دقيق.. لأنك أخي الكريم ببساطة تستطيع أن تضع السكريبت خاصة أخونا الذي يسأل في اجراء مخزن بعد احاطته بمؤشر للمرور على السجلات مع استخدام جدول مؤقت أو متحول من نوع جدول و تضع النتائج فيه ثم تعمل عليها Select و سيعيد بذلك الإجراء Record Set كنتيجة لتنفيذ الإجراء المخزن و ببساطة ستتمكن من استدعائها من البرنامج عن طريق .Net و عرض النتائج سواء في تقرير أو في GridView.

 

تعقيب على البند الثاني و الثالث: بالنسبة لجلب السجلات كنت أقصد جلب المفتاح الأساسي فقط و ليكن Identity Column و جلب 10000 سجل منه لن يستغرق سوى أجزاء من الثانية و قد جربت بنفسي الآن الاستعلام من SQL Server عن طريق الشبكة و استغرق جلب السجلات أجزاء من الثانية كما قلت لك.

 

أما بالنسبة للحل خاصتك هو طبعا أفضل في حال امكانية دمج العبارات في Select Statement واحدة أو أكثر, لكن لم يكن عندي وقت كاف لاستوعب ماذا كان يحاول أخونا أن يصل اليه من السكريبت خاصته.

 

طبعاً قصدت النقاش لنستفيد كلينا و ليس لأخطئك ..

 

تحياتي للجميع

تم تعديل بواسطه imadouzoun
1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

جزاكم الله الف خير 

مشكورين علي تفاعلكم 

عملت هذا الكود  احتلت المشكله من خلال المؤشرات

_____________________________________

بس طلع الكلام المكتوب بالعربي  استفهامات  ؟؟؟؟ ؟؟؟؟؟

 هل يمكنني معالجة الاستفهامات في الكود بدون تغير ال Callation

ALTER proc [dbo].[GetFamilyYatim] @MothersId intasDECLARE @years VARCHAR(40)DECLARE @months VARCHAR(30)DECLARE @days VARCHAR(30)DECLARE @DeceasedName VARCHAR(30)DECLARE @DeceasedCivilRegistry VARCHAR(30)DECLARE @MothersName VARCHAR(30)DECLARE @RecordDowager VARCHAR(30)DECLARE @SonYatem int=0DECLARE @SonMoal int=0DECLARE @SonStudyMoal int=0declare CSon  cursor forSELECT        Deceased.DeceasedName, Deceased.DeceasedCivil_Registry, Deceased_Mothers.MothersName, Deceased_Mothers.RecordDowager,   datediff(year, Deceased_Sons.DateBirth, GETDATE())as YearsFROM            Deceased_Sons INNER JOIN                         Deceased_Mothers ON Deceased_Sons.MothersId = Deceased_Mothers.Id INNER JOIN                         Deceased ON Deceased_Sons.DeceasedId = Deceased.Id AND Deceased_Mothers.Id = Deceased_Sons.MothersId where  [email protected] CSonwhile(@@FETCH_STATUS =0)beginfetch next from CSon into @DeceasedName,@DeceasedCivilRegistry,@MothersName,@RecordDowager,@Yearsif @years<=18 set @[email protected]+1if @years>18 and @years<=22set @[email protected]+1endclose CSondeallocate CSonselect @DeceasedName as DeceasedName,@DeceasedCivilRegistry as DeceasedCivilRegistry,@MothersName as MothersName,@RecordDowager as RecordDowager,@SonYatem as SonYatem,@SonMoal as SonMoal
تم تعديل بواسطه alroaini100
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

أنصح بشدة بتغيير الـ Collation لعمود جدولك الذي يظهر على شكل اشارات استفهام .. لكن يمكنك أن تنجز المطلوب أيضا عن طريق الـ SQL كالتالي:

Select Column_Name Collate Arabic_CS_AI as Column_Name From  Table_Name

Collate Arabic_CS_AI: هذه العبارة ستمكنك ببساطة من تحويل الـ Collation أثناء تنفيذ الاستعلام فقط إلى اللغة العربية.. و اذا اردت لغات اخرى فيمكنك أن تختار احداها من ناتج تنفيذ الاستعلام التالي:

SELECT name, description FROM fn_helpcollations();

بالتوفيق
 

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

من فضلك سجل دخول لتتمكن من التعليق

ستتمكن من اضافه تعليقات بعد التسجيل



سجل دخولك الان

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .