2012-12-15 61 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。事实上,更新帐户没有做任何事情,使我认为它的行事而不是。 –