2016-09-27 3 views
2

Если я пытаюсь оператор SQL с нормальным запросом, он отлично работает так:Debug мое обновление триггера SQL Server

UPDATE TraineeMonthlyShopItemListRecord 
SET Data01 = 1 
WHERE TraineeID = '553' 
    AND ShopItemListID = '17' 
    AND RecordID IN (SELECT a.recordid 
        FROM TraineeMonthlyHourRecord a 
        JOIN MonthlyHourRecord b ON a.RecordID = b.RecordID 
        WHERE b.Month = '201609' 
        AND a.TraineeID = '553' 
        GROUP BY a.RecordID 
        HAVING COUNT(*) = 1) 

Однако он не работает в триггере. Я могу успешно сохранить на курок, но когда я проверить его вручную вставить запись в таблицу, я получаю сообщение об ошибке:

Incorrect syntax near 'MonthlyHourRecord'

Вот мой триггер кода, пожалуйста, посмотрите и посмотреть, что может быть неправды, благодаря!

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

ALTER TRIGGER [dbo].[t2] 
ON [dbo].[TraineeShopItemListRecord] 
AFTER INSERT  
AS  
BEGIN 
    declare @TraineeID varchar(10) 
    declare @MM varchar(10) 
    declare @YYYY varchar(10) 
    declare @ShopItemListID varchar(20) 
    declare @RecordID varchar(10) 
    declare @YYYYMM varchar(10) 
    declare @RecordTime datetime 
    declare @DD varchar(10) declare @test varchar(10) 
    declare @DataDD varchar(10) 
    declare @Quantity varchar(10) 
    declare @SQL nvarchar(200) 

    SELECT @ShopItemListID = ShopItemListID from inserted 
    SELECT @RecordTime = RecordTime from inserted 
    SELECT @Quantity = Quantity from inserted 

    SET @MM = substring(CONVERT(varchar,@RecordTime, 112),5,2) 
    SET @YYYY = substring(CONVERT(varchar,@RecordTime, 112),1,4) 
    SET @DD = substring(CONVERT(varchar,@RecordTime, 112),7,2) 

    SELECT @TraineeID = TraineeID from inserted 

    SET @YYYYMM = @[email protected] 
    SET @DataDD = 'Data'[email protected] 

    SET @SQL = 'UPDATE TraineeMonthlyShopItemListRecord SET  '[email protected]+'='[email protected]+' WHERE TraineeID ='''[email protected]+''' and ShopItemListID='''[email protected]+''' and RecordID IN (SELECT DISTINCT a.RecordID from TraineeMonthlyHourRecord a JOIN MonthlyHourRecord b on a.RecordID = b.RecordID WHERE b.Month ='''[email protected]+''' and a.TraineeID ='''[email protected]+''' GROUP BY a.RecordID HAVING COUNT(*) = 1)' 

    EXEC sp_executesql @SQL 
END 
+1

Ваш триггер ** MAJOR ** недостаток в том, что вы, кажется, предположить, что это будет называться ** один раз в строке ** - это ** не ** случай. Триггер будет срабатывать ** один раз за оператор **, поэтому, если ваш оператор 'INSERT', который вызывает этот триггер для запуска вставки 25 строк, вы получите триггер, запущенный ** один раз **, но тогда псевдо-таблица' Inserted' будет содержат 25 строк. Какой из этих 25 строк будет выбран ваш код? 'SELECT @Quantity = количество от вставленного' - оно не детерминировано, вы получите ** одну произвольную строку **, и вы будете ** игнорируете все остальные строки **. Для этого нужно переписать триггер! –

+0

Спасибо за предложение. Какое направление следует рассмотреть, чтобы переписать его? – autopenta

+0

Необходимо учитывать, что 'Inserted' (и' Deleted') будет содержать ** несколько строк **, и поэтому вам нужно использовать ** set-based ** операции вместо того, чтобы извлекать отдельные значения столбцов. –

ответ

0

В большой для комментариев, поэтому я пишу это в ответе.

Вы можете использовать этот

SELECT TraineeID, 
     ShopItemListID, 
     RecordTime, 
     Quantity, 
     substring(CONVERT(varchar,@RecordTime, 112),1,4)+substring(CONVERT(varchar,@RecordTime, 112),5,2) as YYYYMM 
     'Data'+substring(CONVERT(varchar,@RecordTime, 112),7,2) as DataDD 
FROM inserted 

Чтобы присоединиться к таблицам, которые необходимо обновить.

Дайте этому попытку:

;WITH cte AS (
SELECT TraineeID, 
     ShopItemListID, 
     RecordTime, 
     Quantity, 
     substring(CONVERT(varchar,@RecordTime, 112),1,4)+substring(CONVERT(varchar,@RecordTime, 112),5,2) as YYYYMM 
     'Data'+substring(CONVERT(varchar,@RecordTime, 112),7,2) as DataDD 
FROM inserted 
) 

UPDATE tm 
SET Data01 = c.Quantity 
FROM TraineeMonthlyShopItemListRecord tm 
INNER JOIN cte c 
    ON c.TraineeID = tm.TraineeID 
     AND tm.ShopItemListID = c.ShopItemListID 
CROSS APPLY (
    SELECT a.RecordID 
    FROM TraineeMonthlyHourRecord a 
    INNER JOIN MonthlyHourRecord b 
     ON a.RecordID = b.RecordID 
    WHERE b.Month = c.YYYYMM 
     AND a.TraineeID = c.TraineeID 
    GROUP BY a.RecordID 
    HAVING COUNT(*) = 1 
) a 
WHERE a.RecordID = tm.RecordID 
+0

Большое спасибо за объяснение. – autopenta

+0

Мое удовольствие! Надеюсь, что это поможет вам :) – gofr1

Смежные вопросы