2016-03-07 3 views
0

Эй, ребята, спасибо заранее за любую помощь, у меня есть этот триггер в моем SQL Server 2012 баз данныхSQL Server 2012 Trigger

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 значения строки «метка» и строку «data», как только что-то вставляется в таблицу, но только обновляет строку «данные».

Если я просто выбираю этот кусок кода и запускаю/отлаживаю его, он фактически обновляет обе строки, любую идею, почему это происходит?

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

После Вставки вы используете триггер, чтобы обновить ту же таблицу, в которой установлен триггер. Я бы сделал это с ограничениями по умолчанию и/или вычисляемыми столбцами. –

+0

Я согласен с @TabAlleman здесь. Ваша триггерная логика здесь полностью нарушена. Если вы когда-либо вставляете более 1 строки своей логики, если не собираетесь работать правильно. Вам следует избегать скалярных переменных, и вы также должны ссылаться на вставленные и/или удаленные таблицы в триггеры. –

ответ

-2

Используйте приведенный ниже код. В вашем случае я думаю, что триггер срабатывает перед тем, как выполнить семантикуphrasetable 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 

Это не будет работать, как и другие указали. Если вы вставляете сразу несколько строк, только триггер будет изменен только триггером.

Сделайте JOIN на таблице INSERTED, чтобы получить новые строки, затем еще один JOIN на semantickeyphrasetable(textos, *), чтобы получить значения тегов. Что-то вроде этого:

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

Был ли этот ответ когда-либо решен?

Если нет, то почему бы просто не добавить оба обновления в одну строку вместо двух блоков 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