2015-12-04 3 views
0

В задаче SQL Agent я загружаю данные из основной таблицы (X). Если статус равен «WW» или «WXY», я просто хочу, чтобы все записи вставлялись в другую таблицу (Y), где я создал триггер. Не могли бы вы дать мне совет, что я должен изменить в определении триггера? Я получаю сообщение об ошибке при попытке вставить несколько записей в таблицу DB2.Y (агент задание не удалось)SQL Вставка нескольких записей в таблицу триггеров

Первого кода (загрузка новых данных)

DECLARE @STARTTIME datetime 
DECLARE @TIME datetime 
DECLARE @ENDTIME datetime 

SET @TIME=(SELECT MAX(Time) FROM DB2.Y) 
SET @STARTTIME=(select dateadd(hour,1,getdate())) 
SET @ENDTIME=(SELECT MAX(TIME) FROM DB1.X where TIME is not null) 


IF @TIME = @ENDTIME 
BEGIN 
TRUNCATE TABLE DB2.Y; 
INSERT INTO DB2.Y (Time) Values (@TIME) 
END 
ELSE 
BEGIN 
TRUNCATE TABLE DB2.Y 

INSERT INTO DB2.Y ([Serv],[Status]) 
SELECT [SERV],[STATUS] FROM DB1.X WHERE TIME > @TIME and [SERV]='Description' and ([STATUS]='WW' or [STATUS]='WXY') ; 


UPDATE DB2.Y 
SET [Time]= @ENDTIME 
END 

Код триггера:

USE DB2 
GO 

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 


CREATE TRIGGER [dbo].[TriggerName] ON Y 
AFTER INSERT AS 

DECLARE @SERV varchar(40) 
DECLARE @STATUS varchar(3) 

SET @SERV=(SELECT [SERV] FROM inserted) 
SET @STATUS=(SELECT [STATUS] FROM inserted) 

IF @STATUS in ('WW', 'WXY') 
BEGIN 
DECLARE @MSG varchar(500) 
SET @MSG = 'Job "' + @SERV + '" failed!!!' 

EXEC msdb.dbo.sp_send_dbmail @recipients=N'[email protected]', @body= @MSG, @subject = @MSG, @profile_name = 'profilename' 

END 
+0

'inserted' может содержать несколько записей и ваш код в настоящее время не занимается этим. – Jaco

ответ

0

You может использовать курсор для устранения вашей ошибки. Курсор ниже итерации по всем вставленным записям с STATUS либо WW, либо WXY и отправляет электронное письмо для каждого из них.

DECLARE error_cursor CURSOR FOR 
SELECT [SERV],[STATUS] FROM inserted 
WHERE [STATUS] in ('WW', 'WXY') 

OPEN error_cursor 

FETCH NEXT FROM error_cursor 
INTO @SERV, @STATUS 

WHILE @@FETCH_STATUS = 0 
BEGIN 

    DECLARE MSG varchar(500) 
    SET @MSG = 'Job "' + @SERV + '" failed!!!' 

    EXEC msdb.dbo.sp_send_dbmail @recipients=N'[email protected]', @body= @MSG, @subject = @MSG, @profile_name = 'profilename' 

    FETCH NEXT FROM vendor_cursor 
    INTO @SERV, @STATUS 
END 
CLOSE error_cursor; 
DEALLOCATE error_cursor; 
0

INSERTED может содержать несколько строк для многорядных INSERT - он запускается один раз за операцию, а не один раз в строке.

Попробуйте триггер, как это вместо:

USE DB2 
GO 

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 


CREATE TRIGGER [dbo].[TriggerName] ON Y 
AFTER INSERT AS 

DECLARE @SERV varchar(40) 
DECLARE @STATUS varchar(3) 

IF EXISTS(SELECT [Status] FROM Inserted WHERE [STATUS] in ('WW', 'WXY')) 
BEGIN 
DECLARE @MSG varchar(8000) 

INSERT INTO JobLog(Serv, Status) 
SELECT Serv, Status FROM Inserted WHERE [STATUS] in ('WW', 'WXY') 

SET @MSG = CAST(@@ROWCOUNT as nvarchar) + 'Job(s) failed - see log for details' 

EXEC msdb.dbo.sp_send_dbmail @recipients=N'[email protected]', @body= @MSG, @subject = @MSG, @profile_name = 'profilename' 

END 

SELECT 
0

Попробуйте что-то вроде этого ...

CREATE TRIGGER [dbo].[TriggerName] ON Y 
AFTER INSERT 
AS 
BEGIN 
    SET NOCOUNT ON; 

DECLARE @SERV varchar(40),@STATUS varchar(3), @MSG varchar(500) 

Select [SERV], [STATUS] INTO #Temp 
FROM inserted 
Where [STATUS] IN ('WW', 'WXY') 

Declare Cur CURSOR FOR 
SELECT [SERV], [STATUS] FROM #Temp 

    OPEN Cur 
    FETCH NEXT FROM Cur INTO @SERV, @STATUS 

    WHILE @@FETCH_STATUS = 0 
    BEGIN 
     SET @MSG = 'Job "' + @SERV + '" failed!!!' 

     EXEC msdb.dbo.sp_send_dbmail @recipients=N'[email protected]' 
            , @body= @MSG 
            , @subject = @MSG 
            , @profile_name = 'profilename' 


      FETCH NEXT FROM Cur INTO @SERV, @STATUS  
    END 

    CLOSE Cur 
    DEALLOCATE Cur 

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