有无论如何我可以创建一个触发器,在更新/删除发生之前执行(然后实际更新/删除发生)?以及我如何才能从表中触发drop
?如何在SQL Server 2005中更新触发器之前创建
1
A
回答
0
下降TRIGGER- use database_name
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'tgr_name' AND type = 'TR')
DROP TRIGGER tgr_name
GO
1
这从微软的文章介绍如何创建触发器的语法。
http://msdn.microsoft.com/en-us/library/ms189799.aspx
是不是真的有一个“前”触发,但您可以使用INSTEAD OF触发器,可以让你在任何地方采取行动试图跳,然后定义你自己的行动。
我已经使用该技术来版本化数据。
CREATE TRIGGER [dbo].[Documents_CreateVersion]
ON [dbo].[Documents]
INSTEAD OF UPDATE
AS
BEGIN
DECLARE @DocumentID int
SELECT DocumentID = DocumentID FROM INSERTED
-- do something
END
插入的是一个有点用词不当的位置,但它包含了操作的详细信息时,那么你可以定义与数据你自己的行动之前。
编辑:
按我下面的响应意见,如果多个行一次更新我的例子可能是危险的。我的应用程序不允许这样,所以在这种情况下很好。我会同意上述是不好的做法。
1
下降触发器使用:
--SQL Server 2005+, drop the trigger, no error message if it does not exist yet
BEGIN TRY DROP TRIGGER dbo.TrigerYourTable END TRY BEGIN CATCH END CATCH
GO
--drop trigger pre-SQl Server 2005, no error message if it does not exist yet
if exists (select * from sysobjects where id = object_id(N'[dbo].[TrigerYourTable ]') and OBJECTPROPERTY(id, N'IsTrigger') = 1)
drop trigger [dbo].[TrigerYourTable ]
GO
OP中评论说:
......假设我要检查的 一个perticular用户childcount如果是超过5 不要更新user.how我可以做 ,而不是触发器?
您并不真的需要阻止原始更新,您可以让它发生,然后在触发器中检查问题并在必要时进行回滚。这是如何执行的逻辑,一个或多个受影响的行,当你需要加入,以确定受影响的行childcount
:
--create the trigger
CREATE TRIGGER dbo.TrigerYourTable ON dbo.YourTable
AFTER UPDATE
AS
SET NOCOUNT ON
IF EXISTS (SELECT
1
FROM INSERTED i
INNER JOIN YourChildrenTable c ON i.ParentID=c.ParentID
GROUP BY i.ParentID
HAVING COUNT(i.ParentID)>5
)
BEGIN
RAISERROR('Count of children can not exceed 5',16,1)
ROLLBACK
RETURN
END
GO
它会抛出错误,如果有违反逻辑的,并原始命令将受到回滚。
如果childcount
是受影响的表中的列,然后使用触发器这样执行的逻辑:
--create the trigger
CREATE TRIGGER dbo.TrigerYourTable ON dbo.YourTable
AFTER UPDATE
AS
SET NOCOUNT ON
IF EXISTS (SELECT 1 FROM INSERTED WHERE childcount>5)
BEGIN
RAISERROR('Count of children can not exceed 5',16,1)
ROLLBACK
RETURN
END
GO
如果你只是想忽略违反规则试试这个任何行的更新:
--create the trigger
CREATE TRIGGER dbo.TrigerYourTable ON dbo.YourTable
INSTEAD OF UPDATE
AS
SET NOCOUNT ON
UPDATE y
SET col1=i.col1
,col2=i.col2
,col3=i.col3
,.... --list all columns except the PK column!
FROM dbo.YourTable y
INNER JOIN INSERTED i on y.PK=i.PK
WHERE i.childcount<=5
GO
它只会更新有一个孩子行计数小于5,忽略了失败的需求(没有错误消息)所有受影响行。
0
下面是一个简单的触发器,用于检查列值,并在更新或插入之前触发并引发错误。
IF OBJECT_ID ('dbo.MyTableTrigger', 'TR') IS NOT NULL
DROP TRIGGER dbo.MyTableTrigger;
GO
CREATE TRIGGER MyTableTrigger
ON dbo.MyTable
FOR INSERT, UPDATE
AS
DECLARE @Col1ID INT
DECLARE @Col2ID INT
SELECT @Col1ID = Col1ID, @Col2ID = Col2ID FROM inserted
IF ((@Col1ID IS NOT NULL) AND (@Col2ID IS NOT NULL))
BEGIN
RAISERROR ('Col1ID and Col2ID cannot both be in MyTable at the same time.', 16, 10);
END
嗨,更新删除之前需要执行的实际原因是什么? – Dom 2010-10-27 14:44:00