SQL Server 2012的触发
嗨预先感谢您的任何帮助, 我有这个触发器在我的SQL Server 2012数据库SQL Server 2012的触发
USE Teste_TextMining
CREATE TRIGGER Noticia07032016 ON dbo.textos
AFTER INSERT
AS
DECLARE @ID INT
SET @ID = ( SELECT MAX(ID_texto) FROM dbo.textos)
DECLARE @tag NVARCHAR(MAX)
SET @tag = ( SELECT TOP 1 keyphrase
FROM semantickeyphrasetable(textos, *)
WHERE [email protected])
BEGIN
UPDATE dbo.textos
SET tag = UPPER(@tag)
WHERE ID_texto = @ID
END
BEGIN
UPDATE dbo.textos
SET data = GETDATE()
WHERE ID_texto = @ID
END
GO
正如你可以看到它应该更新2个值的“标签”行和“数据”行,一旦某个东西被插入表中,但它只更新“数据”行。
如果我只是选择这段代码并运行/调试它,它实际上更新两行,任何想法为什么这是hapening?
DECLARE @ID INT
SET @ID = ( SELECT MAX(ID_texto) FROM dbo.textos)
DECLARE @tag NVARCHAR(MAX)
SET @tag = ( SELECT TOP 1 keyphrase
FROM semantickeyphrasetable(textos, *)
WHERE [email protected])
BEGIN
UPDATE dbo.textos
SET tag = UPPER(@tag)
WHERE ID_texto = @ID
END
BEGIN
UPDATE dbo.textos
SET data = GETDATE()
WHERE ID_texto = @ID
END
再次感谢您的帮助和时间。
使用下面的代码。在你的情况下,我认为触发器在semantickeyphrasetable TABLE插入完成之前触发。因此,第一次开始时没有任何更新,因为@tag是空的。
其更好地把扳机子表(如果我们需要更新与子表数据父表。)
USE Teste_TextMining
CREATE TRIGGER Noticia07032016 ON dbo.textos
AFTER INSERT
AS
DECLARE @ID INT
,@tag NVARCHAR(MAX)
SELECT @ID = ID_texto
FROM INSERTED
SET @tag = (
SELECT TOP 1 keyphrase
FROM semantickeyphrasetable(textos, *)
WHERE document_key = @ID
)
UPDATE dbo.textos
SET tag = UPPER(@tag)
,
SET data = GETDATE()
WHERE ID_texto = @ID
GO
注意:当多个插入完成,它就会失败。
同样的问题,标记行仍然返回null – XinkZ
是的,这是因为您在标记值被插入之前获取标记值@XinkZ –
既然您知道此代码不会正常工作,为什么不修复它以便它可以处理多行操作? –
触发器基本上会为每个批处理操作触发一次,所以您应该根据这个现实来执行您的逻辑。这也是SQL精神,它支持基于集合的操作(表现更好)。
所有插入的项目被存储到一个特殊的表,称为inserted
,所以你应该与此表一起知道什么是受到触摸的确切记录:
CREATE TRIGGER Noticia07032016 ON dbo.textos
AFTER INSERT
AS
BEGIN
DECLARE @ID INT
SET @ID = ( SELECT MAX(ID_texto) FROM dbo.textos)
DECLARE @tag NVARCHAR(MAX)
SET @tag = ( SELECT TOP 1 keyphrase
FROM semantickeyphrasetable(textos, *)
WHERE [email protected])
BEGIN
UPDATE Dest
SET tag = UPPER(@tag)
FROM dbo.textos Dest
JOIN inserted I ON I.ID_texto = Dest.ID_texto
WHERE ID_texto = @ID
END
BEGIN
UPDATE Dest
SET data = GETDATE()
FROM dbo.textos Dest
JOIN inserted I ON I.ID_texto = Dest.ID_texto
WHERE ID_texto = @ID
END
END
上面没有测试,但是应该帮助您了解如何着手实际更新插入的记录。
我假设你正在执行下面的查询仅仅是为了获取插入的行:
SELECT MAX(ID_texto) FROM dbo.textos
这是行不通的,正如其他人指出。如果一次插入多行,则只有该集合中的最后一个将被触发器修改。
在INSERTED表上执行JOIN以获取新行,然后在semantickeyphrasetable(textos, *)
上执行另一个JOIN以获取标记值。类似这样的:
USE Teste_TextMining
CREATE TRIGGER Noticia07032016 ON dbo.textos
AFTER INSERT
AS
BEGIN
UPDATE T
SET tag = UPPER(K.keyphrase), data = GETDATE()
FROM dbo.textos T
JOIN INSERTED ON INSERTED.ID_texto = T.ID_texto
LEFT JOIN (
SELECT TOP 1 document_key, keyphrase
FROM semantickeyphrasetable(textos, *)
) K ON K.document_key=T.ID_texto
END
GO
这个答案有没有解决?
如果没有,为什么不直接在一行中添加两个更新而不是有2个BEGIN ... END块?
CREATE TRIGGER Noticia07032016 ON dbo.textos
AFTER INSERT
AS
BEGIN
DECLARE @ID INT
SET @ID = ( SELECT MAX(ID_texto) FROM dbo.textos)
DECLARE @tag NVARCHAR(MAX)
SET @tag = ( SELECT TOP 1 keyphrase
FROM semantickeyphrasetable(textos, *)
WHERE [email protected])
BEGIN
UPDATE Dest
SET tag = UPPER(@tag), data = GETDATE()
FROM dbo.textos Dest
JOIN inserted I ON I.ID_texto = Dest.ID_texto
WHERE ID_texto = @ID
END
END
插入后,您正在使用触发器更新触发器所在的同一张表。我会用Default约束和/或计算列代替它。 –
我同意@TabAlleman在这里。你的触发逻辑在这里也完全被打破了。如果你插入多于一行的话,你的逻辑如果不能正常工作的话。你应该避免标量变量,你也应该在触发器中引用插入和/或删除的表。 –