ورود

View Full Version : سوال: از چه روشی برای نوشتن این Trriger استفاده کنم؟



SYNDROME
جمعه 03 خرداد 1387, 15:27 عصر
با سلام
من دو تا جدول زیر را دارم.


Tbl_Head : ID , State
Tbl_Detail: ID , Num

ID کلید جدول Tbl_Head و کلید خارجی جدول Tbl_Detail است.
زمانی که رکوردی از جدول Tbl_Head پاک می کند کل رکوردهای مرتبط با آن از جدول Tbl_Detail پاک می شود
من می خواهم یک Trigger بنویسم که در زمان Delete شدن رکوردهای Tbl_Detail اگر ،یلد State رکورد مرتبط با آنها در Tbl_Head اگر 1 بود عملی را انجام دهدم.
مشکل اینجاست که زمانی که Trigger جدول Detail فراخوانی می شود رکود در Head پاک شده است.
من از AFTER Delete ، For Delete هم استفاده کردم ولی فایده ندارد.
خودم به این 2 روش رسیدم:
فیلد State را در Detail ذخیره کنم.
2-رکورد Head را در زمان Delete به یک جدول Temp موقت انتقال بدهم و در Triger جدول Detail از آن استفاده کنم.
3-اول Detail را پاک کنم و بعد Head را.
می خواستم بدانم روشی دیگری وجود دارد که بتوانم این کار را انجام دهدم؟
با تشکر از دوستان

ASKaffash
شنبه 04 خرداد 1387, 09:34 صبح
با سلام
شما باید از Trigger از نوع Instead Of استفاده کنید اگر مشکل داشتی بگو کمک کنیم

SYNDROME
شنبه 04 خرداد 1387, 19:22 عصر
با سلام
شما باید از Trigger از نوع Instead Of استفاده کنید اگر مشکل داشتی بگو کمک کنیم
Instead OF چه زمانی اجرا می شود؟
استفاده کردم ولی چون Detail با جدول Head ارتباط دارد اجازه ساختن چنین Trigger را به من نمی دهد.
موفق باشید

Arghavan_Reza
دوشنبه 06 خرداد 1387, 12:35 عصر
با سلام مشکل شما به روش زیر حل می شود:


Tbl_Head : ID , State
Tbl_Detail: ID , Num, Tbl_Head_ID



ID کلید جدول Tbl_Head و کلید خارجی جدول Tbl_Detail است.

به فرم زیر اصلاح شود:
ID کلید جدول Tbl_Head و Tbl_Head_ID کلید خارجی جدول Tbl_Detail است.
ضمنا تیک CasCade Delete Related Records را بردارید.
بعد تریگر حذف Tbl_Head را به فرم زیر بنویسید:


CREATE TRIGGER [Tbl_Head_Delete] ON [dbo].[Tbl_Head]
INSTEAD OF DELETE
AS
IF (SELECT STATE FROM DELETED) = 1
BEGIN
DELETE FROM Tbl_Detail WHERE Tbl_Head_ID = (SELECT ID FROM DELETED)
DELETE FROM Tbl_Head WHERE ID = (SELECT ID FROM DELETED)
END
ELSE
RAISERROR('You can not DELETE record!', 16, 1)

موفق باشید.

SYNDROME
دوشنبه 06 خرداد 1387, 21:12 عصر
با سلام مشکل شما به روش زیر حل می شود:


Tbl_Head : ID , State
Tbl_Detail: ID , Num, Tbl_Head_ID


به فرم زیر اصلاح شود:
ID کلید جدول Tbl_Head و Tbl_Head_ID کلید خارجی جدول Tbl_Detail است.
ضمنا تیک CasCade Delete Related Records را بردارید.
بعد تریگر حذف Tbl_Head را به فرم زیر بنویسید:


CREATE TRIGGER [Tbl_Head_Delete] ON [dbo].[Tbl_Head]
INSTEAD OF DELETE
AS
IF (SELECT STATE FROM DELETED) = 1
BEGIN
DELETE FROM Tbl_Detail WHERE Tbl_Head_ID = (SELECT ID FROM DELETED)
DELETE FROM Tbl_Head WHERE ID = (SELECT ID FROM DELETED)
END
ELSE
RAISERROR('You can not DELETE record!', 16, 1)

موفق باشید.
من در این روش مشکلی که دارم به Deleted و Inserted جدول Detail دسترسی ندارد.
برای این کار باید چه کار کنم؟
با تشکر از شما

AminSobati
سه شنبه 07 خرداد 1387, 19:59 عصر
- Trigger از نوع FOR و AFTER یکی هستند
- عمل Delete از Master شروع میشه یا از Detail؟ اگر از Master شروع میشه که همونجا State رو دارین. اگر از Detail شروع میشه که رکورد Master وجود داره. این موضوع رو کمی شفاف کنین لطفا

SYNDROME
سه شنبه 07 خرداد 1387, 21:11 عصر
- Trigger از نوع FOR و AFTER یکی هستند
- عمل Delete از Master شروع میشه یا از Detail؟ اگر از Master شروع میشه که همونجا State رو دارین. اگر از Detail شروع میشه که رکورد Master وجود داره. این موضوع رو کمی شفاف کنین لطفا
1-بین جدول Head وDetail ارتباط بر قرار کرده ام که اگر Head حذف شد detail نیز حذف شود.
2-عمل Delete را روی Head انجام می دهم و مثلماً Detail هم حذف می شود.
حالا در زمانی که جدول Detail پاک می شود می خواهم اگر فیلد State در جدول Head برابر -0 بود عملیاتی را انجام دهم
حالا که می خواهم چنین Trigger برای Detail نوشته ام رکورد مورد نظر در جدول Head پاک شده است.
من در بالا اشاره کردم برای نگه داشتن رکورد Head در زمان حذف Head مقدار مورد نظر را در یک table دیگر ذخیره می کنم و در عملیات Detail استفاده می کنم.
حالا می خواهم ببینم آیا راه حل بهتری وجود دارد تا این عملیات را انجام دهم.
با تشکر از همه دوستان

Arghavan_Reza
چهارشنبه 08 خرداد 1387, 18:02 عصر
DELETE FROM Tbl_Detail WHERE Tbl_Head_ID = (SELECT ID FROM DELETED)
DELETE FROM Tbl_Head WHERE ID = (SELECT ID FROM DELETED)

اگر به تریگری که نوشته ام دقت نمایید اول Detail حذف میشود بعد Head. لذا در تریگر حذف Detail رکورد Head وجود دارد لذا هر چه دوست دارید بنویسید:

CREATE TRIGGER [Tbl_Detail_Delete] ON [dbo].[Tbl_Detail]
FOR DELETE
AS
DECLARE @ID INTEGER
SET @ID = (SELECT DISTINCT Tbl_Head_ID FROM DELETED)
IF (SELECT State FROM Tbl_Head WHERE ID = @ID) = 1
{Some Commands}

hamid.y
دوشنبه 03 اسفند 1388, 10:20 صبح
با سلام خدمت اساتید محترم
یه سوال داشتم لطفا کمکم کنید.
می خوام یه Instead of Insert Trigger بسازم و یه شرط رو چک کنم و یه پیغام yes/no در Interface (سی شارپ) به کاربر بدم.
در صورت جواب بلی رکورد در جدول درج بشه در غیر اینصورت دکورد درج نشه.
حالا با Raiserror فقط میشه یه پغام اطلاعاتی به کاربر داد و نه یه پیغام تعاملی.
آیا اصلا می بایست از Trigger استفاده کرد؟

AminSobati
دوشنبه 03 اسفند 1388, 23:21 عصر
سلام دوست عزیزم،
بهتر بود سوال رو در تاپیک مجزا مطرح میکردید.
به طور کلی، SQL Server با اینترفیس نرم افزار تعاملی نداره. مگر اینکه از طریق raiserror که خودتون اشاره کردین اجرای برنامه رو از SQL Server به اینترفیس بازگشت بدین. ولی سوال اینجاست که چرا اصلا این کار باید در Trigger انجام بشه؟ فرضا اگر SP برای Insert دارین چرا اونجا چک نمیکنین؟