2012-12-15 106 views
7

我有幾個問題試圖解決一個SQL觸發器,以自動將用戶設置爲阻止&在另一個表中創建包含日期的塊記錄if其截止日期等於設定的日期。T-SQL插入觸發器插入,在多個表上如果條件更新

問題是,當觸發器被插入關閉時,print語句被執行併發生插入,但插入到表中卻沒有,或者update語句?誰能解釋爲什麼?

注意:insert和Update語句在單獨執行時都可以。

Account表

CREATE TABLE [dbo].[Account](
[AccountNo] [int] IDENTITY(1,1) NOT NULL, 
[CustomerNo] [int] NOT NULL, 
[PaymentNo] [int] NULL, 
[CreditNo] [int] NULL, 
[BlockID] [dbo].[number] NULL, 
[Balence] [dbo].[currency] NOT NULL, 
[AmountDue] [dbo].[currency] NOT NULL, 
[DueDate] [dbo].[dates] NULL, 
[AutherisedBy] [nvarchar](50) NOT NULL, 
[DateCreated] [date] NOT NULL, 

BLOCKEDUSER表

CREATE TABLE [dbo].[BlockedUsers](
[BlockID] [int] IDENTITY(1,1) NOT NULL, 
[DateEnforced] [dbo].[dates] NOT NULL, 
[Blocked] [dbo].[switch] NOT NULL, 

TRIGGER

ALTER TRIGGER [dbo].[Add_Blocked_User] 
ON [dbo].[Account] 
FOR INSERT 
AS 
BEGIN 
SET NOCOUNT ON; 

Declare @ID int 
Select @ID = [AccountNo] from inserted 
If(Select [DueDate] from inserted) = '2011-01-01' 

INSERT INTO dbo.BlockedUsers(DateEnforced,Blocked) 
VALUES (GETDATE(),1) 
PRINT 'New Block Date Added' 

UPDATE Account 
Set BlockID = IDENT_CURRENT('BlockID') 
where @ID = @ID 
PRINT 'Account Blocked' 

END 

GO 

工作的完整示例:使用幫助下完成的。

ALTER TRIGGER [dbo].[Add_Blocked_User] 
ON [dbo].[Account] 
AFTER INSERT 
AS 
BEGIN 

SET NOCOUNT ON; 

Declare @ID int 
Select @ID = [AccountNo] from inserted 
If(Select [DueDate] from inserted)Not Between (select CONVERT(date, getdate() - 30)) And (select CONVERT(date, getdate())) 
Begin 
    INSERT INTO dbo.BlockedUsers(DateEnforced,Blocked) 
    VALUES (GETDATE(),1) 
    PRINT 'New Block Date Added' 

    UPDATE Account 
    Set BlockID = (Select Max(BlockID) From BlockedUsers) 
    where [AccountNo] = (Select [AccountNo] from inserted) 
    PRINT 'Account Blocked' 
End 

END 

GO 
+4

你的觸發將打破。 –

回答

5

在Transact-SQL的IF語句中的條件後,預計單個語句:

IF condition 
    statement; 

如果你想在同一分支執行多條語句,則必須將他們在BEGIN/END「括號「:

IF condition 
BEGIN 
    statement; 
    statement; 
    ... 
END; 

在你的觸發,只有INSERT語句執行根據的(Select [DueDate] from inserted) = '2011-01-01'條件的結果。至於PRINT和UPDATE,它們都無條件執行,即在之後每插入Account。所以,你可能需要添加BEGINEND周圍INSERT,UPDATE和兩個打印:當兩個或多個行得到插入一條語句

... 
If(Select [DueDate] from inserted) = '2011-01-01' 
BEGIN 
INSERT INTO dbo.BlockedUsers(DateEnforced,Blocked) 
VALUES (GETDATE(),1); 
PRINT 'New Block Date Added'; 

UPDATE Account 
Set BlockID = IDENT_CURRENT('BlockID') 
where @ID = @ID; 
PRINT 'Account Blocked'; 
END; 
... 
+0

Thankyou Andy,這幫我讓我的if條件正常工作,現在我擴展到使用系統狀態,只有當截止日期> 30天時才能阻止。榮譽,真的很感激。 – Baggerz

-1

你做

FOR INSERT 

你想用

AFTER INSERT, UPDATE 

FOR INSERT告訴SQL服務器,你的觸發將完全取代正常插入操作。 AFTER INSERT告訴Sql Server繼續並插入該行,然後執行此代碼作爲後處理步驟。

+8

'FOR INSERT'和'AFTER INSERT'在Transact-SQL中意味着相同。它是「INSTEAD OF INSERT」替代實際操作。 –

+0

Thankyou Andy,這幫助我得到更新和插入正常工作。非常感謝。 – Baggerz

+1

對不起,我:(從來沒有使用FOR。事實上,更新帳戶沒有做任何事情,使我認爲它的行事而不是。 –