Bru*_*oLM 30 sql t-sql sql-server triggers sql-server-2008
我有桌子 Tb
ID | Name | Desc
-------------------------
1 | Sample | sample desc
Run Code Online (Sandbox Code Playgroud)
我想在INSERT上创建一个触发器,它将改变插入的值Desc,例如:
INSERT INTO Tb(Name, Desc) VALUES ('x', 'y')
Run Code Online (Sandbox Code Playgroud)
会导致
ID | Name | Desc
-------------------------
1 | Sample | sample desc
2 | x | Y edited
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,我得到了插入的值,将其Desc更改为大写并添加edited到最后.
这就是我需要的,得到Desc插入和修改它.
我怎样才能做到这一点?
插入更新后处理它会更好吗?或者使用INSTEAD OF INSERT触发并在每次表结构更改时修改它?
Sha*_*nce 38
使用后插入触发器.从inserted伪表加入Tb主键.然后更新desc的值.像:(但可能无法编译)
CREATE TRIGGER TbFixTb_Trg
ON Tb
AFTER INSERT
AS
BEGIN
UPDATE Tb
SET DESC = SomeTransformationOf(i.DESC)
FROM Tb
INNER JOIN inserted i on i.Id = Tb.Id
END
GO
Run Code Online (Sandbox Code Playgroud)
在插入发生之后但在insert语句完成之前发生此触发器.因此,新的,不正确的值已经放在目标表中.在添加,删除列等时,不需要更改此触发器.
在触发器触发之前强制执行警告完整性约束.因此,您不能设置检查约束来强制执行正确形式的DESC.因为这会导致语句在触发器有机会修复任何内容之前失败.(请在依赖它之前仔细检查这一段.自从我写了一个触发器以来已经有一段时间了.)
Jon*_*nVD 26
我不确定你将在哪里获得desc的实际新值,但我认为你是从另一个表或其他表中获取它.但是你可能有理由想要这样做,所以下面就是我如何去做的一个例子.
你想要的是一个名为INSTEAD OF INSERT的触发器,它会激活你而不是桌面上的插入物.
CREATE TRIGGER trgUpdateDesc
ON Tb
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO Tb (Name, [Desc])
SELECT Name, [Desc] + 'edited'
FROM inserted
END
GO
Run Code Online (Sandbox Code Playgroud)
我在那里硬编码了'编辑'这个词,因为我不确定你想要获取值的位置,但你可以很容易地用另一个表中的变量或值替换它.
哦还要确保把[]放在Desc周围,因为它是sql server中的一个关键词(代表降序)
希望有所帮助!
编辑:
如果你想让它更加健壮,以便它不依赖于表结构那么多你可以使用AFTER INSERT触发器来更新那个字段.
CREATE TRIGGER [dbo].[trgUpdateDesc]
ON [dbo].[Tb]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
UPDATE Tb
SET [Desc] = UPPER(inserted.[Desc]) + ' Edited'
FROM inserted INNER JOIN Tb On inserted.id = Tb.id
END
Run Code Online (Sandbox Code Playgroud)
临时表可以帮助使用INSTEAD OF INSERT触发器,同时避免显式列出所有不相关的表列:
CREATE TRIGGER trgUpdateDesc
ON Tb
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON;
select * into #tmp from inserted;
UPDATE #tmp SET Desc = Desc + 'edited' --where ...;
insert into Tb select * from #tmp;
drop table #tmp;
END
Run Code Online (Sandbox Code Playgroud)
将新列添加到表中时,不需要修复此代码.
另请注意,SQL Server会针对批量DML操作触发一次,并且必须正确处理多行插入.