الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

مثال حول الحلقات التكرارية في TSQL

مغلق
بدأه خضر ترزي في 11 مايو 2002 · 5 رد · 4,542 مشاهدة · في أرشيف قسم SQL Server
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

في الكثير من الاحيان قد تحتاج الى Stored Procedure للقيام بعملية احتساب معينة، بالطبع عبارات ال SQL البسيطة بامكانها القايم باحتسابات كثيرة و بصورة شاملة على الجدول بكامله، و لكن في بعض الاحيان فانت تحتاج الى حلقة تكرارية للقيام باحتساب ما

الحلقة التكرارية سوف تسمح لك بالوصول الى السجلات واحد بعد الاخر للقيام بمعالجتهم.

بالطبع بامكانك بناء Modle في قاعدة البيانات و استخدام ADO للقيام بكل العملية بلغة فيجوال بيزك ، و لكن ان انتبهت قليلا سوف تلاحظ بان ذلك ال Module يقوم بسحب البيانات عبر الشبكة من SQL Server الى الجهاز لاحتسابها و من ثم ارجاعها ، و بذلك سوف يصبح البرنامج بطيئ خصوصا اذا الاحتساب او العملية المطلوبة على السجلات معقدة و طويلة و عدد السجلات كبير.

الطريقة الثانية لحل المشكلة لمحبي فيجوال بيزك للتطبيقات هي فصل ال Module من قاعدة البيانات عبر ال Microsoft Office Developer XP و حفظه في ملف DLL و تخزينه في الجهاز المركزي و تعريفه في DCOM+. و بالطبع ربطه مع قاعدة البيانات في الجهاز العادي.

الطريقة الساقة بسيطة جدا حيث انها لن تحتاج الا الى امرين اضافيين لربط و سوف تنهي مسئلة تحريك عدد هائل من البيانات عبر الشبكة حيث ان ملف ال DLL و الذي يحتوي على ال function او ال Sub التي تقوم بالعملية هي على نفس الجهاز المركزي.

السرعة سوف تزيد كثيرا و لكنها لن تصل الى اقصى حد ممكن لها

الحد الاقصى الممكن هو بناء كود TSQL للقيام بالعملية ، احد الامور التي تبعد الكثيرين من استخدامه هو تخوفهم من الحلقات التكرارية، حيث كل المطلوب هي بناء Stored Procedure في Microsoft Access و عند النقر المزدوج عليها او عبر استدعائها بواسطة الكود سوف تنفذ مباشرة في الجهاز المركزي في SQL Server.

عملية بسيطة للغاية اليس كذلك :) ؟

اليكم الكود المطلوب لحلقة تكرارية

DECLARE Employee_Cursor CURSOR FOR
SELECT LastName, FirstName FROM Northwind.dbo.Employees
OPEN Employee_Cursor
FETCH NEXT FROM Employee_Cursor
WHILE @@FETCH_STATUS = 0
BEGIN

  ضع هنا الكود المطلوب بداخل الحلقة
   FETCH NEXT FROM Employee_Cursor
END
CLOSE Employee_Cursor
DEALLOCATE Employee_Cursor
#2

أشكرك أخي خضر على هذه المعلومات القيمة ، و هذه مساندة مني بأضافات بسيطة

للفائدة ..

** حفظ البيانات في المتغييرات بواسطة INTO

DECLARE @fname varchar(40), @lname varchar(40)
FETCH NEXT FROM Employee_Cursor
  INTO @fname,@lname
WHILE @@FETCH_STATUS = 0
BEGIN
--يمكنك أستخدام المتغيرات المعرفة في الصف الأول هنا 
--مثال:
Print @fname + "  "+ @lname
--ضع هنا الكود المطلوب بداخل الحلقة
   FETCH NEXT FROM Employee_Cursor
    INTO @fname,@lname
END

** تحديث البيانات الناتجة بواسطة CURRENT OF

بهذه الطريقة : تقرأ البيانات أولا ثم تحدث مباشرة

DECLARE @fname varchar(40), @lname varchar(40)
DECLARE @Salary decimal(8,2)
DECLARE Employee_Cursor CURSOR FOR
SELECT LastName, FirstName,Salary FROM 
Northwind.dbo.Employees 
Where Salary Between 1000 AND 2000 
OPEN Employee_Cursor
FETCH NEXT FROM Employee_Cursor
  INTO @fname,@lname,@Salary
WHILE @@FETCH_STATUS = 0
BEGIN
--مثال:
Select @Salary = @Salary + 0.25 * @Salary
-- أضافة 25% زيادة براتب الموظف
UPDATE Northwind.dbo.Employees 
  Set Salary = @Salary 
  Where CURRENT OF Employee_Cursor
-- حدث بيانات الصف الحالي
--ضع هنا الكود المطلوب بداخل الحلقة
   FETCH NEXT FROM Employee_Cursor
    INTO @fname,@lname,@Salary
END
CLOSE Employee_Cursor
DEALLOCATE Employee_Cursor
#3

بارك الله فيكما يا م/خضر ويا MR.ASP

أعتقد وجود خطأ بسيط فى الكود السابق ل_MR.ASP

أعتقد أنه نتيجة سرعة الكتابة لا أكثر

والغرض هو تعميم الفائدة للجميع ليس إلا

فى السطر 13

كلمة Set توضع محل Select

أخوكم أبو سارة

#4

يعطيك العافية أخوي أبو سارة

يمكنك أستخدام Select أو Set لأعطاء قيم للمتغيرات

و لا يوجد فرق بينهما حيب علمي في MsSQL 2000 ...

تستخدم Set في تشغيل و أطفاء بعض الأوامر في ال MsSQL

مثل:

SET NOCOUNT ON

أو

SET NOCOUNT OFF

#5

الاختلاف الوحيد بين SET و SELECT في Tranact SQL هي ان Select سوف تعطي قيمة للمتغير و ترجع هذه القيمة للمستخدم ايضا، اما Set فسوف تعطي القيمة فقط و لا ترجع شيئ.

#6

أنا كنت أعتقد كذا أول ، بس لاحظت الفرق بين أستعمالات Select لأعطاء المتغيير قيمة.

أعطاء المتغير قيمة بدون عرضها

Select @Variable=Value

لعرض القيمة

Select @Variable

و الفرق بين Select و Set في هذا المجال :

في الأولى يمكنك أعطاء قييم لمتغيرات كثيرة بنفس الجملة

Select @Variable1=Value1 , @Variable2=Value2,

,.....,@VariableN=ValueN

أما Set لا يمكن أستعمالاها بهذه الطريقة، كل متغيير له جملة خاصة به

شغل هذا الكود و غير Select إلى Set و العكس

Use TempDb 
IF EXISTS (SELECT name 
	   FROM   sysobjects 
	   WHERE  name = N'temp1' 
	   AND    type = 'U')
    DROP TABLE temp1
GO
Create TABLE temp1(Col DateTime)
GO
Delete From Temp1

GO
Set NOCount ON
DECLARE @NewDate DateTime,@N INT
Select @N=1
  While @N <= 10
 Begin
  Select @NewDate = GetDate() - @N*10
  Select @N=@N + 1
-- يمكن وضع الجملتين السابقتين بجملة واحدة
--   Select @NewDate = GetDate() - @N*10,@N=@N + 1
  Insert INTO temp1 Values ( @NewDate  )
 End

Set NOCount OFF
GO

هذا الموضوع مغلق.

مواضيع مشابهة