2016-03-07 107 views
0

嗨預先感謝您的任何幫助, 我有這個觸發器在我的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 

再次感謝您的幫助和時間。

+1

插入後,您正在使用觸發器更新觸發器所在的同一張表。我會用Default約束和/或計算列代替它。 –

+0

我同意@TabAlleman在這裏。你的觸發邏輯在這裏也完全被打破了。如果你插入多於一行的話,你的邏輯如果不能正常工作的話。你應該避免標量變量,你也應該在觸發器中引用插入和/或刪除的表。 –

回答

-2

使用下面的代碼。在你的情況下,我認爲觸發器在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 

注意:當多個插入完成,它就會失敗。

+0

同樣的問題,標記行仍然返回null – XinkZ

+0

是的,這是因爲您在標記值被插入之前獲取標記值@XinkZ –

+0

既然您知道此代碼不會正常工作,爲什麼不修復它以便它可以處理多行操作? –

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 [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 

上面沒有測試,但是應該幫助您瞭解如何着手實際更新插入的記錄。

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 
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 [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