PDA

View Full Version : مشکل با تریگرها



rasoolgh
شنبه 16 دی 1385, 09:32 صبح
من این triger را نوشتم
CREATE TRIGGER SetMande ON [dbo].[T2]
FOR INSERT
AS
declare @mybes money
declare @mybed money
declare @myman money
declare @myID int
select @mybes=bes from inserted
select @mybed=bed from inserted
select @myID = ID1 from inserted
select top 1 @myman=mymande from t1
update t2 set mande=@myman+@mybes-@mybed where id1 = @myID
update t1 set mymande =@myman+@mybes-@mybed

در حالت عادی دزست کار میکنه یعنی وقتی درsqlserver یه رکورد رو دستی اضاف می کنم
ولی وقتی از دستور زیر استفاده می کنم درست جواب نمیده
INSERT INTO T2
(bed, Bes)
SELECT Bed, bes
FROM T3

rasoolgh
شنبه 16 دی 1385, 10:28 صبح
من چطوری باید این مشکل رو حل کنم
در ضمن این TRIGGER رو روی AFTER INSERT IL هم چک کردم باز هم جواب نداد
با تشکر

rasoolgh
شنبه 16 دی 1385, 10:29 صبح
من چطوری باید این مشکل رو حل کنم
در ضمن این TRIGGER رو روی AFTER INSERT هم چک کردم باز هم جواب نداد
با تشکر

iman_s52
شنبه 16 دی 1385, 10:31 صبح
فکر کنم چون گروهی Insert می کنی اعمال نمیشه ؟؟

rasoolgh
شنبه 16 دی 1385, 11:20 صبح
راه حل چیه ؟

iman_s52
شنبه 16 دی 1385, 11:49 صبح
اگه می تونی با Stored Procedure پیاده سازی کن.
با Fetch می تونی یه حلقه درست کنی و یکی یکی کارت رو انجام بدی ؟

whitehat
شنبه 16 دی 1385, 14:27 عصر
به نظر من بهتره برای این کار از Computed Column استفاده کنید، تریگر باعث کاهش سرعت شما می شود ! بهتره حتی الامکان از تریگر استفاده نکنید

rasoolgh
یک شنبه 17 دی 1385, 07:07 صبح
من با Computed Column کار نکردم اگر ممکن است یک مثال برای من بیاورید
با تشکر

whitehat
یک شنبه 17 دی 1385, 07:55 صبح
کافیه یک فیلد از نوع Money تعریف کنید و فرمول محاسباتی آنرا برابر bes-bed بگذارید، با این کار فقط کافیه در تریگر جدول دوم را Update کنید
(برای تعریف این نوع Column می توانید در مشخصات آن در شاخه Computed Column در قسمت فرمول آن عبارت بالا را قرار دهید)

SabaSabouhi
یک شنبه 17 دی 1385, 10:45 صبح
با سلام
همانطور که یکى از دوستان گفتند مشکل شما در تعداد سطرها هست. چون شما از متغیرهایى استفاده مى‌کنید که اطلاعاتشان را از جدول Inserted مى‌گیرند و اگر این جدول بیش از یک سطر داشته باشد شما فقط اطلاعات یک سطر را دریافت مى‌کنید. براى حل این مشکل دو راه حل هم وجود دارد:
1. در Trigger خود کنترل کنید که فقط یک سطر Insert شود و اگر تعداد سطرها بیشتر بود عمل Insert را Rollback کنید.



IF (Select Count(*) FROM Inserted) > 1 Rollback



2. در Trigger خود از متغیر استفاده نکنید و تمام عملیات را با فرامین SQL انجام دهید. هر چند که این‌یکى کمى کارتان را مشکل مى‌کند اما دیگر محدودیت تعداد سطر را نخواهید داشت.

صبا صبوحى

AminSobati
یک شنبه 17 دی 1385, 23:27 عصر
IF (Select Count(*) FROM Inserted) > 1 Rollback

از متغیر RowCount@@ استفاده کنید



در Trigger خود از متغیر استفاده نکنید و تمام عملیات را با فرامین SQL انجام دهید. هر چند که این‌یکى کمى کارتان را مشکل مى‌کند اما دیگر محدودیت تعداد سطر را نخواهید داشت


من هم موافقم ولی نمیشه بعنوان یک نسخه تجویز کرد چون متاسفانه همیشه امکانپذیر نیست



در حالت عادی دزست کار میکنه یعنی وقتی درsqlserver یه رکورد رو دستی اضاف می کنم
ولی وقتی از دستور زیر استفاده می کنم درست جواب نمیده


زمانیکه چند رکورد با یک دستور Insert وارد جدول میشن، همگی در Inserted هم قرار میگیرند و لذا دستور:
select @mybes=bes from inserted
باعث میشه فقط آخرین رکورد به شما برگرده. در چنین حالتی یا باید از Cursor استفاده کنید یا مقاله ای که در صفحه اصلی همین Forum گذاشتم مطالعه بفرمایید!

odiseh
چهارشنبه 20 دی 1385, 08:23 صبح
با سلام
همانطور که یکى از دوستان گفتند مشکل شما در تعداد سطرها هست. چون شما از متغیرهایى استفاده مى‌کنید که اطلاعاتشان را از جدول Inserted مى‌گیرند و اگر این جدول بیش از یک سطر داشته باشد شما فقط اطلاعات یک سطر را دریافت مى‌کنید. براى حل این مشکل دو راه حل هم وجود دارد:
1. در Trigger خود کنترل کنید که فقط یک سطر Insert شود و اگر تعداد سطرها بیشتر بود عمل Insert را Rollback کنید.



IF (Select Count(*) FROM Inserted) > 1 Rollback



2. در Trigger خود از متغیر استفاده نکنید و تمام عملیات را با فرامین SQL انجام دهید. هر چند که این‌یکى کمى کارتان را مشکل مى‌کند اما دیگر محدودیت تعداد سطر را نخواهید داشت.



صبا صبوحى


یعنی اگه موقع update چندین رکورد update بشن ما همیشه در جداول مجازی inserted , deleted فقط به یه رکورد دسترسی داریم نه بیشتر ؟

whitehat
چهارشنبه 20 دی 1385, 11:34 صبح
شما به همه رکورد های Update شده دسترسی دارید ، و در صورتی که جدول شما PrimeryKey داشته باشد و خودش Update نشده باشه براحتی می توانید بفهمید چه فیلدهایی بروز شده ، و مقدار قبلی آن چه بوده.کافیه جدول Inserted و Deleted را با هم بر اساس کلید اصلی Join کنید.

SabaSabouhi
چهارشنبه 20 دی 1385, 22:47 عصر
یعنی اگه موقع update چندین رکورد update بشن ما همیشه در جداول مجازی inserted , deleted فقط به یه رکورد دسترسی داریم نه بیشتر ؟

سلام
خیر، به تمام رکوردها دسترسى داریم به شرط این که از خود جداول inserted و deleted استفاده کنید. اما اگر از فرمان Select @MyCol = MyCol FROM Inserted استفاده کنید فقط یک سطر از جدول را بدست آورده‌اید و نه تمام آن را.

صبا صبوحى