SQL Server 2012触发器

时间:2016-03-07 12:52:46

标签: sql-server 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 document_key=@ID)
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个值“tag”行和“data”行,但它只更新“data”行。

如果我只是选择这段代码并运行/调试它,它实际上会更新这两行,不知道为什么这是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 document_key=@ID)
    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

再次感谢您的帮助和时间。

4 个答案:

答案 0 :(得分:1)

我假设您只是为了获取插入的行而执行以下查询:

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

答案 1 :(得分:0)

触发器基本上会为每个批处理操作触发一次,因此您应该根据这个现实来执行逻辑。这也是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 document_key=@ID)

    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

以上内容未经过测试,但可以帮助您了解如何继续实际更新已插入的记录。

答案 2 :(得分:0)

这个答案有没有得到解决?

如果没有,为什么不在一行中添加两个更新而不是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 document_key=@ID)

  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

答案 3 :(得分:-2)

使用以下代码。在你的情况下,我认为触发器是在完成semantickeyphrasetable TABLE插入之前触发的。所以首先更新没有,因为@tag是空的。

最好将触发器放在子表中。(如果我们需要使用子表数据更新Parent表。)

    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

注意:完成多次插入后,它将失败。