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

سوال عن ترايقر في sql server

بدأه السيد الهاشمي في 26 مارس 2012 · 14 رد · 1,133 مشاهدة · في ASP.NET
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

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

عندي مشكلة في ترايقر .. اريد ان انشى تريقر .. خاص بجدول الاستعار عمل هذه الترايقر .. انه يقوم بالبحث عن الكتاب هل هو مستعار ام لا .. في حال انه مستعار يقوم بالغاء عملية الانسرت .. ويخبر اللمستخدم ان هذه الكتاب تم استعارته

قمة بنشاء هذه الترايقر ولكن لا اعلم ما هي المشكلة .. لاني اول مرة استخدم ترايقر .. وياليت الي عندة خبرة بالترايقر يوضح لي ايش الخطاء ويعدل على الترايقر .. ولكم جزيل الشكر والتدقير

ALTER TRIGGER insrt_book 
on ast
for insert as 
 DECLARE @id_book int
 DECLARE @b_flag int
  if @id_book=@id_book and @b_flag=1
  begin

  print('sorry u cant give thies book')
  rollback transaction 

end
#2

السلام عليكم...

alter TRIGGER insrt_book 
on ast
for insert as 
 DECLARE @id_book int
 DECLARE @b_flag int
 set @b_flag = 0
 select @id_book=id_book from inserted
 select @b_flag = b_flag from ast
	where id_book = @id_book 

  if @b_flag = 1
  begin
	raiseerror ('sorry u cant give this book')
	rollback transaction
  end

inserted هو جدول وهمي يحوي السجلات المراد اضافتها

على نفس المبدأ هناك جدول وهمي اسمه deleted يحوي السجلات المراد حذفها

أما في حال تعديل سجل ما فيمكنك الوصول إلى القيم في هذا السجل باستخدام الجدولين الوهميين السابقين معا، حيث:

deleted هو السجل المراد تعديله و فيه الحقيم قبل التعديل

inserted هو الجدول الذي يجوي السجل المراد تعديله و فيه القيم الجديدة

أي كأننا نتعامل مع التعديل على أنه حذف للسجل و إعادة إضافته بالقيم الجديدة

ملاحظة: كل من الجدولين الوهميين: (inserted, deleted) يمكن أن يحوي أكثر من سجل و يمكن التعامل معهما كما نتعامل مع الجداول الحقيقية

و الله أعلم

تم تعديل هذه المشاركة بواسطة byte101 في 26 مارس 2012 في 05:57

1

لاتـُهيئ كفني ما متّ بعد = لم يزل في أضلعي برقٌ و رعدُ


أنــا اسـلامــي ..أنا عزّته = أنا خيل الله نحو النصــر تعــدو


أنــا تــاريـخـي …ألا تعــرفـه = خـالد ينبض في روحــي و سعدُ


لاتـــغرنـك منــي هدأتـــــي = لا يمــوت الثــأر و لــكن يســتعـدُ


لا يغرنـــك نصــلٌ موغـــلٌ = في عروقي …فـأنا منه أحـّـــدُ


إن ما ضُيع في ساح الوغى = في سوى ساحــاتـها لا يــستردُ


#3
byte101 كتب:

السلام عليكم...

alter TRIGGER insrt_book 
on ast
for insert as 
 DECLARE @id_book int
 DECLARE @b_flag int
 set @b_flag = 0
 select @id_book=id_book from inserted
 select @b_flag = b_flag from ast
	where id_book = @id_book 

  if @b_flag = 1
  begin
	raiseerror ('sorry u cant give this book')
	rollback transaction
  end

inserted هو جدول وهمي يحوي السجلات المراد اضافتها

على نفس المبدأ هناك جدول وهمي اسمه deleted يحوي السجلات المراد حذفها

أما في حال تعديل سجل ما فيمكنك الوصول إلى القيم في هذا السجل باستخدام الجدولين الوهميين السابقين معا، حيث:

deleted هو السجل المراد تعديله و فيه الحقيم قبل التعديل

inserted هو الجدول الذي يجوي السجل المراد تعديله و فيه القيم الجديدة

أي كأننا نتعامل مع التعديل على أنه حذف للسجل و إعادة إضافته بالقيم الجديدة

ملاحظة: كل من الجدولين الوهميين: (inserted, deleted) يمكن أن يحوي أكثر من سجل و يمكن التعامل معهما كما نتعامل مع الجداول الحقيقية

و الله أعلم

-------------------------------------

مشكور اخي العزيز على ردك لي بس اخي جربت الي كتبته لي وطلع لي هذه الخطاء

The requested operation requires a SqlClr context, which is only available when running in the Sql Server process.
#4

السلام عليكم

هل هذا الخطأ يظهر عندمحاولة انشاء الـ trigger أم عند التنفيذ؟

هل تستخدم sql server express أم غيره (enterprise مثلا)

ما هو اصدار ال visual studioالذي تستخدمه

1

لاتـُهيئ كفني ما متّ بعد = لم يزل في أضلعي برقٌ و رعدُ


أنــا اسـلامــي ..أنا عزّته = أنا خيل الله نحو النصــر تعــدو


أنــا تــاريـخـي …ألا تعــرفـه = خـالد ينبض في روحــي و سعدُ


لاتـــغرنـك منــي هدأتـــــي = لا يمــوت الثــأر و لــكن يســتعـدُ


لا يغرنـــك نصــلٌ موغـــلٌ = في عروقي …فـأنا منه أحـّـــدُ


إن ما ضُيع في ساح الوغى = في سوى ساحــاتـها لا يــستردُ


#5
byte101 كتب:

السلام عليكم

هل هذا الخطأ يظهر عندمحاولة انشاء الـ trigger أم عند التنفيذ؟

هل تستخدم sql server express أم غيره (enterprise مثلا)

ما هو اصدار ال visual studioالذي تستخدمه

=================

اخي العزيز .. التريقر اشتغل بنجاح بس لا يحقق المطلوب منه .. انا اريدة .. لو اول مرة عملت استعارة للكتاب يسوي استعارة بنجاح .. ويخلي قيمة b_flag=1 بس لو جيت مرة ثانية اسوي استعارة لنفس للكتاب .. المفروض يرفض ويطلع لي رسالة انه هذه الكتاب تم استعارته .

واريدة كمان يتحقق .. من count حق الكتاب .. اذا كان صفر لايقبل الاستعارة .. ام لو كان اكبر من الصفر يسوي استعارة .. وثاني شي اخي العزيز.. لا اريدة ان يطلع لي ارر مثل هذه

-------------------------------

The transaction ended in the trigger. The batch has been aborted.

sorry u cant give thies book

----------------------------------------------------------

اريدة ان يطلع لي رسالة خطاء من غير ما يخرج من الصفحة .. لكن هنا يطلع لي خطاء في الصفحة .. اتمنا اني اكون اوصلت الفكرة لك

#6

السلام عليكم

اقتباس
The requested operation requires a SqlClr context, which is only available when running in the Sql Server process.

اقتباس
اخي العزيز .. التريقر اشتغل بنجاح بس لا يحقق المطلوب منه

هل هذا يعني أن الرسالة السابقة لم تعد تظهر؟

اقتباس
انا اريدة .. لو اول مرة عملت استعارة للكتاب يسوي استعارة بنجاح .. ويخلي قيمة b_flag=1 بس لو جيت مرة ثانية اسوي استعارة لنفس للكتاب .. المفروض يرفض ويطلع لي رسالة انه هذه الكتاب تم استعارته .

بالنسبة للكود لا يوجد فرق بين أول مرة و غيرها

اقتباس
واريدة كمان يتحقق .. من count حق الكتاب .. اذا كان صفر لايقبل الاستعارة .. ام لو كان اكبر من الصفر يسوي استعارة .. وثاني شي اخي العزيز.. لا اريدة ان يطلع لي ارر مثل هذه

لم تذكر موضوع عدد الكتب سابقا...

أحتاج إلى بعض التوضيح لأتمكن من مساعدتك..

ماذا يمثل الجدول الذي بحاول أن نضيف سجلات له؟ ما هي الأعمدة التي يحويها؟

أقترح عليك البنية التالية:

جدول اسمه books فيه الأعمدة التالية:

Id, Name, ....., TotalCount, availableCount

عندما تريد أن تعرف كتاب جديد (أي أحضرت كتاب جديد إلى المكتبة) عندها تقوم بعملية insert على هذا الجدول

أما في حالة أردت إعارة الكتاب فأنت تحتاج إلى عمل update على هذا الجدول و ليس insert

و من الأفضل أن يكون هناك جدول آخر اسمهالإعارات مثلا فيه الأعمدة التالية:

Id, clustomerId, bookId, lendingDate, LendingDuration

بالإضافة غلى جدول customers الذي سيرتبط معه العمود customerId من جدول الإعارات

أرجو توضيح بنية قاعدة البيانات التي تعتمدها (الجداول و الأعمدة في كل منها) حتى أتمكن من مساعدتك

متى تظهر رسالة الخطأ هذه؟

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

السؤال في البداية كان سؤال قواعد بيانات، صراحة أنا لست خبيرا ببرمجة الويب

في برمجة الويندوز، من الأفضل أن تجعل قاعدة البيانات تعيد خطأ باستخدام raiseerror ثم تتعامل معه من خلال try...catch

و لكن لدي اقتراح، لماذا لا تتأكد من توافر الكتاب قبل أن تمكّن المستخدم من اختياره؟

1

لاتـُهيئ كفني ما متّ بعد = لم يزل في أضلعي برقٌ و رعدُ


أنــا اسـلامــي ..أنا عزّته = أنا خيل الله نحو النصــر تعــدو


أنــا تــاريـخـي …ألا تعــرفـه = خـالد ينبض في روحــي و سعدُ


لاتـــغرنـك منــي هدأتـــــي = لا يمــوت الثــأر و لــكن يســتعـدُ


لا يغرنـــك نصــلٌ موغـــلٌ = في عروقي …فـأنا منه أحـّـــدُ


إن ما ضُيع في ساح الوغى = في سوى ساحــاتـها لا يــستردُ


#7
byte101 كتب:

السلام عليكم

هل هذا يعني أن الرسالة السابقة لم تعد تظهر؟

بالنسبة للكود لا يوجد فرق بين أول مرة و غيرها

لم تذكر موضوع عدد الكتب سابقا...

أحتاج إلى بعض التوضيح لأتمكن من مساعدتك..

ماذا يمثل الجدول الذي بحاول أن نضيف سجلات له؟ ما هي الأعمدة التي يحويها؟

أقترح عليك البنية التالية:

جدول اسمه books فيه الأعمدة التالية:

Id, Name, ....., TotalCount, availableCount

عندما تريد أن تعرف كتاب جديد (أي أحضرت كتاب جديد إلى المكتبة) عندها تقوم بعملية insert على هذا الجدول

أما في حالة أردت إعارة الكتاب فأنت تحتاج إلى عمل update على هذا الجدول و ليس insert

و من الأفضل أن يكون هناك جدول آخر اسمهالإعارات مثلا فيه الأعمدة التالية:

Id, clustomerId, bookId, lendingDate, LendingDuration

بالإضافة غلى جدول customers الذي سيرتبط معه العمود customerId من جدول الإعارات

أرجو توضيح بنية قاعدة البيانات التي تعتمدها (الجداول و الأعمدة في كل منها) حتى أتمكن من مساعدتك

متى تظهر رسالة الخطأ هذه؟

السؤال في البداية كان سؤال قواعد بيانات، صراحة أنا لست خبيرا ببرمجة الويب

في برمجة الويندوز، من الأفضل أن تجعل قاعدة البيانات تعيد خطأ باستخدام raiseerror ثم تتعامل معه من خلال try...catch

و لكن لدي اقتراح، لماذا لا تتأكد من توافر الكتاب قبل أن تمكّن المستخدم من اختياره؟

--------------------------------------

مشكور اخي العزيز تعبتك معاي كثير.. الله يجعلة في ميزان حسناتك .. بالنسبة للي ذكرت لي .. اول شي الكود اشتغل والرسالة القديمة لم تعد تطلع ابداّ

--------------------------------------------------------

ثانيا: الرسالة التي اصبحت تطلع لي هي الرسالة الي نكتبها في الترييقر .. اما عندما اقوم بكتابة raiseerror التريقر مايقبلها ..؟ مادري ليش

----------------------------------------

ثالثاُ : بالنسبة للحداول . انا عندي تقريباُ نفس الذي ذكرتها .. يعني عندي جدول خاص بالكتب .. وجدول خاص بالاستعارة . وجدول خاص بالزبون .. في انا مضيف بيانات اخرى للتواصل .. بس اغلب الي قلته موجود :

-------------------------------

بالنسبة للعملية التاكد من وجود الكتاب قبل عملية الاستعارة ... اخي العزيز .. اريدة ان تتم عن طريق التريقر . ... لاني استطيع حل المشكلة هاذي كاملة برمجياُ لكن .. طلب مني ان استخدم التريقر ... في هذه العملية .. ولك جزيل الشكر ..

ياليت تعدل لي على التريقر على حسب الجداول التالية :

book :

id_book :

book_name :

book_count:

book_flag : لتاكد من ان الكتاب جديد :

------------------

الجدول الثاني جدول الاستعارة :

id_Loan

id_book:

date_Loan

date_back:

flag_check:لتاكد من ان الكتاب مستعار ام لا

id_costmer:

---------------------

عندي جدول خاص بالزبون لكنه طويل .. لاني عملت بياناات كثيرة فيه .. ولكن انا رابطة مع جدول الاستعارة

ياليت تعدل لي التريقر على حسب هذه الجداول ولك جزيل الشكر اخي العزيز

#8

السلام عليكم

اقتباس
book_flag : لتاكد من ان الكتاب جديد :

لم أفهم ما علاقة كون الكتاب جديد بموضوع الإعارة. أظن أننا لا نحتاج هذا العمود فيما يخص الإعارة

اقتباس
flag_check:لتاكد من ان الكتاب مستعار ام لا

هل بينة الجداول التي ذكرتها مفروضة عليك كما هي و عليك الالتزام بها أم أنك أنت من وضعها؟

خصوصا العمود السابق (flag_check) إذ لا داعي لهذا العمود.

من الأفضل أن يكون جدول الإعارة كمرجع لعمليات الإعارة التي قائمة حالياً أو السابقة. و أن يتم التحقق من توافر الكتاب من خلال عمود يحوي عدد النسخ الحالية المتوافرة من الكتاب كما أوضحت في ردي السابق

أعتذر عن كثرة الأسئلة و لكنني أحاول أن نصل إلى الحل الأقرب للحل المثالي. إن أردت الأمر أن يتم كما هو، أرجو أن تخبرني بذلك

1

لاتـُهيئ كفني ما متّ بعد = لم يزل في أضلعي برقٌ و رعدُ


أنــا اسـلامــي ..أنا عزّته = أنا خيل الله نحو النصــر تعــدو


أنــا تــاريـخـي …ألا تعــرفـه = خـالد ينبض في روحــي و سعدُ


لاتـــغرنـك منــي هدأتـــــي = لا يمــوت الثــأر و لــكن يســتعـدُ


لا يغرنـــك نصــلٌ موغـــلٌ = في عروقي …فـأنا منه أحـّـــدُ


إن ما ضُيع في ساح الوغى = في سوى ساحــاتـها لا يــستردُ


#9
byte101 كتب:

السلام عليكم

لم أفهم ما علاقة كون الكتاب جديد بموضوع الإعارة. أظن أننا لا نحتاج هذا العمود فيما يخص الإعارة

هل بينة الجداول التي ذكرتها مفروضة عليك كما هي و عليك الالتزام بها أم أنك أنت من وضعها؟

خصوصا العمود السابق (flag_check) إذ لا داعي لهذا العمود.

من الأفضل أن يكون جدول الإعارة كمرجع لعمليات الإعارة التي قائمة حالياً أو السابقة. و أن يتم التحقق من توافر الكتاب من خلال عمود يحوي عدد النسخ الحالية المتوافرة من الكتاب كما أوضحت في ردي السابق

أعتذر عن كثرة الأسئلة و لكنني أحاول أن نصل إلى الحل الأقرب للحل المثالي. إن أردت الأمر أن يتم كما هو، أرجو أن تخبرني بذلك

--------------------------

اخي العزيز انا من وضع البنية حق الجدول .. طيب اخي كيف اقوم بالتحقق من عدد النسخ من جدول الكتب قبل عملية الاعارة .. بحيث لو كان عدد النسخ = 0 يطلع لي رسالة يقول لي لايمكن الاستعارة لان عدد النسخ يساوي 0 ؟

كيف اطبق هذه بالتريقر ياليت تقولي لاني بحاجة الية ضروري يوم غداُ

#10

السلام عليكم

أخي الكريم أقترح أن تكون بنية الجداول كالتالي:

جدول اسمه books فيه الأعمدة التالية:

Id, Name, ....., TotalCount, availableCount

جدول آخر اسمه Lends مثلا فيه الأعمدة التالية:

Id, customerId, bookId, lendingDate, LendingDuration

بالإضافة غلى جدول customers الذي سيرتبط معه العمود customerId من جدول الإعارات

و ال trigger يكون كالتالي:

alter TRIGGER lend_book 
on lends
for insert as 
 DECLARE @book_id int
 DECLARE @count_available int

 set @book_id = 0;
 set @count_available = 0;

 select @bookId = bookId from inserted;
 select @count_available = availableCount from books;
    	where id = @book_id;

  if @count_available > 0
  begin
    	update books
		set availableCount = availableCount - 1
		where id = @book_id;
  end
  else
  begin
		raiseerror ('sorry u cant give this book');
    	rollback transaction;
  end;

  GO

كون المطلوب منك هو استخدام الـ trigger فلا بد من استخدام عبارة raiseerror التي ستعيد خطأ إلى البرنامج. البرنامج سيتعامل معها و يظهرها بالطريقة التي تريد من خلال try...catch

و لا مشكلة في ذلك إذ أن عملية الـ insert لم تتم بسبب وجود عبارة: rollback transaction

الـ trigger مرتبط بجدول الإعارات و لكنه يقرأ و يعدل على جدول الكتب

يقوم الـtrigger عند محاولة الإدخال (إعارة جديدة) يفحص عدد النسخ المتوافرة من الكتاب في جدول الكتب فإن كان أكبر من 0 ينقص القيمة بمقدار 1 و تتم عملية الإدخال في جدول الإعارة

و إلا فلا تتم.

1

لاتـُهيئ كفني ما متّ بعد = لم يزل في أضلعي برقٌ و رعدُ


أنــا اسـلامــي ..أنا عزّته = أنا خيل الله نحو النصــر تعــدو


أنــا تــاريـخـي …ألا تعــرفـه = خـالد ينبض في روحــي و سعدُ


لاتـــغرنـك منــي هدأتـــــي = لا يمــوت الثــأر و لــكن يســتعـدُ


لا يغرنـــك نصــلٌ موغـــلٌ = في عروقي …فـأنا منه أحـّـــدُ


إن ما ضُيع في ساح الوغى = في سوى ساحــاتـها لا يــستردُ


#11
byte101 كتب:

السلام عليكم

أخي الكريم أقترح أن تكون بنية الجداول كالتالي:

جدول اسمه books فيه الأعمدة التالية:

Id, Name, ....., TotalCount, availableCount

جدول آخر اسمه Lends مثلا فيه الأعمدة التالية:

Id, customerId, bookId, lendingDate, LendingDuration

بالإضافة غلى جدول customers الذي سيرتبط معه العمود customerId من جدول الإعارات

و ال trigger يكون كالتالي:

alter TRIGGER lend_book 
on lends
for insert as 
 DECLARE @book_id int
 DECLARE @count_available int

 set @book_id = 0;
 set @count_available = 0;

 select @bookId = bookId from inserted;
 select @count_available = availableCount from books;
    	where id = @book_id;

  if @count_available > 0
  begin
    	update books
		set availableCount = availableCount - 1
		where id = @book_id;
  end
  else
  begin
		raiseerror ('sorry u cant give this book');
    	rollback transaction;
  end;

  GO

كون المطلوب منك هو استخدام الـ trigger فلا بد من استخدام عبارة raiseerror التي ستعيد خطأ إلى البرنامج. البرنامج سيتعامل معها و يظهرها بالطريقة التي تريد من خلال try...catch

و لا مشكلة في ذلك إذ أن عملية الـ insert لم تتم بسبب وجود عبارة: rollback transaction

الـ trigger مرتبط بجدول الإعارات و لكنه يقرأ و يعدل على جدول الكتب

يقوم الـtrigger عند محاولة الإدخال (إعارة جديدة) يفحص عدد النسخ المتوافرة من الكتاب في جدول الكتب فإن كان أكبر من 0 ينقص القيمة بمقدار 1 و تتم عملية الإدخال في جدول الإعارة

و إلا فلا تتم.

----------------------------------------------------

مشكور اخي العزيز .. الله يرضى عليك .. ماقصرت والله خلاص انحلت المشكلة بس بقي شي واجد عندما اكتب raiseeror اماعند كتابة print تنكتب ليش ؟ لااعلم لماذا ؟

#12

السلام عليكم

ما فهمت السؤال أخي الكريم

print تستخدم لطباعة قيمة نصية على شاشة الconsole

raiseerror لتوليد خطأ على مستوى قاعدة البيانات و بالتالي تستطيع التعامل معه باستخدام try...catch

أرجو التوضيح إن لم أكن قد أجبت على السؤال

1

لاتـُهيئ كفني ما متّ بعد = لم يزل في أضلعي برقٌ و رعدُ


أنــا اسـلامــي ..أنا عزّته = أنا خيل الله نحو النصــر تعــدو


أنــا تــاريـخـي …ألا تعــرفـه = خـالد ينبض في روحــي و سعدُ


لاتـــغرنـك منــي هدأتـــــي = لا يمــوت الثــأر و لــكن يســتعـدُ


لا يغرنـــك نصــلٌ موغـــلٌ = في عروقي …فـأنا منه أحـّـــدُ


إن ما ضُيع في ساح الوغى = في سوى ساحــاتـها لا يــستردُ


#13
byte101 كتب:

السلام عليكم

ما فهمت السؤال أخي الكريم

print تستخدم لطباعة قيمة نصية على شاشة الconsole

raiseerror لتوليد خطأ على مستوى قاعدة البيانات و بالتالي تستطيع التعامل معه باستخدام try...catch

أرجو التوضيح إن لم أكن قد أجبت على السؤال

----------------------

اخي العزيز المقصود اني اريد ان اطبع الخطاء الذي اكتبة في التريقر عبر ليبل .. لكن لا اعلم ماهي الطريقة ما التريقر الي كتبتة لي كان صحيح اخي العزيز ونحلت المشكلة باقي بس كيف اطبع رسالة الخطاء الي اكتبها في التريقر عبر ليبل في الصفحة

#14

السلام عليكم

الكود في الصفحة يكون كالتالي:

try
{
//كود الاستعارة هنا
}
catch (Exception ex)
{
label1.Text = ex.message;
}

و يبقى كود ال trigger كما هو (أي باستخدام raiserror)

1

لاتـُهيئ كفني ما متّ بعد = لم يزل في أضلعي برقٌ و رعدُ


أنــا اسـلامــي ..أنا عزّته = أنا خيل الله نحو النصــر تعــدو


أنــا تــاريـخـي …ألا تعــرفـه = خـالد ينبض في روحــي و سعدُ


لاتـــغرنـك منــي هدأتـــــي = لا يمــوت الثــأر و لــكن يســتعـدُ


لا يغرنـــك نصــلٌ موغـــلٌ = في عروقي …فـأنا منه أحـّـــدُ


إن ما ضُيع في ساح الوغى = في سوى ساحــاتـها لا يــستردُ


#15
byte101 كتب:

السلام عليكم

الكود في الصفحة يكون كالتالي:

try
{
//كود الاستعارة هنا
}
catch (Exception ex)
{
label1.Text = ex.message;
}

و يبقى كود ال trigger كما هو (أي باستخدام raiserror)

----------------------------------------

مشكور اخي العزيز ماقصرت والله

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