Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在SQL Server上编辑触发器中插入的值?_Sql_Sql Server_Sql Server 2008_Tsql_Triggers - Fatal编程技术网

如何在SQL Server上编辑触发器中插入的值?

如何在SQL Server上编辑触发器中插入的值?,sql,sql-server,sql-server-2008,tsql,triggers,Sql,Sql Server,Sql Server 2008,Tsql,Triggers,我有表Tb ID | Name | Desc ------------------------- 1 | Sample | sample desc 我想在INSERT上创建一个触发器,该触发器将更改insertingDesc的值,例如: INSERT INTO Tb(Name, Desc) VALUES ('x', 'y') 将导致 ID | Name | Desc ------------------------- 1 | Sample | sample desc 2 | x

我有表
Tb

ID | Name   | Desc
-------------------------
 1 | Sample | sample desc
我想在INSERT上创建一个触发器,该触发器将更改inserting
Desc
的值,例如:

INSERT INTO Tb(Name, Desc) VALUES ('x', 'y')
将导致

ID | Name   | Desc
-------------------------
 1 | Sample | sample desc
 2 | x      | Y edited
在上面的例子中,我得到了inserting
Desc
的值,将其改为大写,并在末尾添加了
edited

这就是我需要的,获取插入的
Desc
,并对其进行修改

我该怎么做


在插入后进行更新是否更好?或者使用INSERT而不是INSERT生成触发器,并在每次表结构更改时对其进行修改?

您可能希望查看
而不是
触发器

CREATE TRIGGER Tb_InsteadTrigger on Tb
INSTEAD OF INSERT
AS
BEGIN
...

这将允许您在数据进入表之前对其进行操作。触发器负责将数据插入表中。

我不确定从何处获取desc的实际新值,但我假设您是从另一个表或类似的表中获取的。但是你可能有这样做的理由,所以下面是一个我将如何去做的例子

您需要的是一个INSTEAD OF INSERT触发器,它使用您提供的每个逻辑在表上触发而不是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
我在这里硬编码了“edited”一词,因为我不确定要从哪里获取值,但您可以轻松地用变量或其他表中的值替换它

哦,还要确保在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 

使用插入后触发器。从插入的
伪表连接到主键上的
Tb
。然后更新desc的值,比如:(但可能无法编译)

此触发器发生在插入之后,但在
insert
语句完成之前。因此,新的、不正确的值已放置在目标表中。在添加、删除列时,不需要更改此触发器


警告在后触发器触发之前强制执行完整性约束。因此,不能使用check约束来强制执行适当形式的DESC。因为这会导致在触发器有机会修复任何内容之前语句失败。(在依赖它之前,请仔细检查此段落。我已经有一段时间没有编写触发器了。)

临时表可以帮助使用
而不是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 
将新列添加到表中时,不需要修复此代码

但是要小心


还请注意,SQL Server为批量DML操作触发一次fire,并且必须触发。

不要使用IDENTITY,而是使用UNIQUEIDENTIFIER和NEWID()


你不能换一种方式吗?我个人讨厌当我看到数据上发生奇怪的事情时,我终于意识到一个幽灵触发器正在做一些事情,我将用它来修复一个来自我无法访问的代码的问题。它插入一个项目的
url
,但它不会删除重音符号和特殊字符,我会让触发器为我这样做。这并不是一个很难的概念,它让我觉得微软不能提供像Oracle那样的简单功能,在Oracle中,你可以在插入之前通过编辑:新值来修改任何值。i、 e.如果我想在插入用户名之前总是将用户名强制转换为upper(假设出于某种原因我不能在代码中这样做),那么可以使用一个before-insert触发器:NEW.username:=upper(:NEW.username)。但是,在SQL Server中,不能对插入的临时表中的值进行等效,这真的很糟糕。是的,可以。在instead of触发器中,只需运行insert语句,将插入表中的所有列选择到实际表中,但修改要设置为上限的列的select。例如,在insert而不是insert触发器中,只需运行类似于
insert into Table(a,b,c)的语句,从inserted中选择a,ToUpper(b),c。微软技术公司将甲骨文从水中击退。我想获取插入的
Desc
的值并对其进行修改。我应该这么说。我会更新我的问题,很抱歉,如果我的表更改了怎么办?我每次都要更新触发器?难道没有其他方法可以做到这一点吗?此外,此解决方案不会使实际插入的值可用于
输出
子句!在这种情况下,“Trgt”是什么?@CodenameCain是个错误。应该是
Tb
,或者from子句需要是
fromtrb-Trgt
。感谢您捕捉到这一点。这会产生以下错误:只有在使用列列表且打开identity_INSERT时,才能为表“Tb”中的identity列指定显式值。@Anders,我想,这种方法可能与列不兼容。但您也可以尝试将此列放到触发器内的
#tmp
表中。
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 
CREATE TRIGGER MyTrigger ON MyTable INSTEAD OF INSERT AS BEGIN
; select * into #MyTriggertTempTable from inserted
; update #MyTriggertTempTable set ID=NEWID() where ID is null
; insert into MyTable select * from #MyTriggertTempTable
END