2016-11-26 66 views
0

我需要建立在SQL Server是有條件解僱當用戶試圖刪除表中的行觸發。SQL Server觸發器:如何獲取觸發器的where子句中的查詢字符串中使用的值?

我在數據庫Airlines 2個表:

  • Passenger - 它有乘客的信息。我需要在這個表上創建觸發器,顯然

  • Record - 它記錄了飛行(S)的乘客已經上

我的觸發應該工作如下:

如果乘客從來沒有上過航班,如果嘗試過,它應該被刪除。 但是,如果他/她有不是在航班上,它應該限制行動並打印他在任何航班上的次數。

的唯一的事情(我希望)我與掙扎是:

我怎麼會指定查詢內的任何WHERE條款的觸發,如果我不知道我需要尋找,直到用戶其特定的乘客試圖刪除它?

那麼,長話短說:有沒有什麼辦法可以獲得在查詢的WHERE子句中傳遞的值,以便在觸發器中使用?

非常感謝您的時間!

這裏是我的代碼:

ALTER TRIGGER Restrict_Delete 
ON Records 
INSTEAD OF DELETE 
AS 
BEGIN 
    DECLARE @r_count INT 

    SET @r_count = (SELECT DISTINCT COUNT(*) 
        FROM Passenger P, Records R 
        WHERE P.passenger_id = R.passenger_id 
         AND P.passenger_id = ???) 

    IF @r_count > 0 
    BEGIN 
     ROLLBACK TRAN 
     PRINT ('Permission denied. ' + CAST (@r_count AS Varchar(3)) + ' record(s) exist.') 
    END 
    ELSE 
     PRINT 'No records exist. Record deleted!' 
    END 

我如何確定我的查詢中的passenger_id?

+2

這是功課?防止孤立飛行記錄的最好方法是外鍵而不是觸發器。 –

+1

[壞習慣踢:使用舊樣式的JOIN(http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/08/bad-habits-to-kick-using-old-style-joins。 ASPX) - 舊樣式* *風格是與*適當* ANSI'JOIN'在ANSI語法替換表的逗號分隔的列表 - ** ** 92 SQL標準(**超過20年**月)並且不鼓勵使用 –

回答

2

您可以使用deletedinserted表!

這些是存在於觸發器中幷包含從實際表複製的記錄的特殊表。當您更改表格中的一行時,舊行的副本將進入deleted表格,並且新行的副本將進入inserted表格。既然你只是刪除,你只需要使用deleted表。

這裏的SQL如何能看看你的觸發器中:

DECLARE @r_count INT 
SET @r_count = Count(*) 
FROM Records R -- You don't actually need the Passenger table for this. 
WHERE r.Passenger_id IN (
     select d.Passenger_id 
     from Deleted d 
    ) 
IF @r_count > 0 
BEGIN 
     Rollback Tran 
     PRINT ('Permission denied. ' + CAST (@r_count AS Varchar(3)) + ' record(s) exist.') 
END 
ELSE 
     PRINT 'No records exist. Record deleted!' 

有些事情,你需要知道的,雖然:觸發每一次的語句調用,記錄每一次也沒有。所以如果你用一條DELETE語句刪除兩個乘客,你將只能得到一個觸發器。您擁有的邏輯(以及我改編的)將檢查該DELETE語句刪除的任何記錄。如果您正在進行批量刪除,您可以獲得相當多的@r_count

如果您需要周圍的代碼,儘量避免在您的觸發器使用遊標實際上是:它會使刪除很​​慢。

此外,請注意,PRINT語句將出現在SSMS中,並且可以在ADO.NET中用一些小竅門進行檢索,但不會出現在跟蹤中或作爲記錄集的一部分返回。如果您需要記錄此故障,則需要寫入數據庫表。

+0

非常感謝您花時間回答我的問題。 所以,如果哪一個用戶試圖在一次只有2名乘客,1至2名刪除滿足乘客在觸發指定的條件? 我認爲,這將導致兩個乘客的缺失,因爲@r_count將大於0? – Harjot

+0

這是正確的。正如馬丁·史密斯在他的評論中指出的,如果你的目的是防止刪除具有現有航班的乘客,你會自動地,如果你實現了一個外鍵這個行爲。使用觸發器來實現它沒有太多的實際優勢。如果您需要記錄無法刪除的記錄,則可以在刪除之前使用查詢確定該記錄。 –