2016-03-01 2 views
1

Что не так с этим кодом.SQL Trigger после обновления вставки

Если я типа как этот

Declare tmp as CURSOR FOR 
Select i.ID from Inserted 
OPEN tmp 

Или, если я типа

Declare tmp as CURSOR FOR 
Select i.ID from Deleted 
OPEN tmp 

работает как шарм, но

Есть ли способ, что я могу написать что-то вроде этого

if @operation <> 3 

set @tmp = 'SELECT i.id FROM inserted i ' 

else 

set @tmp =' SELECT i.id FROM deleted i ' 

DECLARE tmpUpit CURSOR FOR 
@tmp 
OPEN tmpUpit 

Редактировать:

CREATE TRIGGER [dbo].[ax_Triger] ON [dbo].[extraTable] 
FOR INSERT, UPDATE, DELETE AS 

    SET NOCOUNT ON; 
--Capture the Operation (Inserted, Deleted Or Updated) 

    DECLARE @operation int 
    DECLARE @Count AS INT 

    SET @operation = 1 

    SELECT @Count = COUNT(*) 
    FROM DELETED 

    IF @Count > 0 
     BEGIN 
      SET @operation = 3 

      SELECT @Count = COUNT(*) 
      FROM INSERTED 

      IF @Count > 0 
      SET @operation = 2 
     END 
DECLARE tmpUpit CURSOR FOR 
SELECT i.id FROM inserted i 
OPEN tmpUpit 
FETCH NEXT FROM tmpUpit 
into @ID WHILE @@fetch_status = 0 

begin If Not exists 
(SELECT * FROM mytable 
where (Operation=3 OR (Operation=1 AND [email protected])) AND Status = 0 AND Tablename ='extraTable') 

begin INSERT INTO 
mytable ([Field1], [Field2], 
[ID], [Tablename], [Operation], [Time12], [Status]) 
VALUES (@Field1, @Field2, @ID, 'extraTable', @operation,GETDATE(),0) 

DELETE FROM mytable 
WHERE [Field1][email protected] And [Field2][email protected] And [ID][email protected] And [Tablename]='extraTable' 
AND [Operation] = 4 AND [Status] = 0 
End 
FETCH NEXT FROM tmpUpit into @ID 
End CLOSE tmpUpit DEALLOCATE tmpUpit end 

мне нужно вставить значение из одной таблицы в другую в зависимости о состоянии Ввел/обновлено/удален

+2

Зачем вам нужен курсор в первую очередь? Они ужасно неэффективны. Подход, который вы пытаетесь, не будет работать, потому что вы перешли в динамическую sql-область. Если вы можете опубликовать некоторые сведения о том, что пытается выполнить ваш триггер, мы можем помочь вам найти подход на основе набора, который не требует указателя. –

+0

@SeanLange я просто нажал edit .. Это мой первый триггер – myString

+0

@myString, вы можете объявить его условно, вы даже можете передать переменную курсора в качестве параметра в SP. Для этого вам не нужен динамический sql. Но почему-то я предполагаю, что вам нужно «ПОЛНОЕ ПРИСОЕДИНЕНИЕ». –

ответ

1

Это совершенно непроверенные, так как структуры таблиц размещены не соответствует размещенной код триггера. Это должно, по крайней мере, продемонстрировать, как вы можете переосмыслить об этом как заданную логику, а не строку из-за агонистической строки.

CREATE TRIGGER [dbo].[Trigger212] ON [dbo].[Towns] 
FOR INSERT, UPDATE, DELETE AS 
BEGIN 
    SET NOCOUNT ON; 

    DECLARE @operation int 
    DECLARE @Variable1 nvarchar(8) = 'Woof' 
    DECLARE @Variable2 nvarchar(4) = 'Foof' 

    --Capture the Operation (Inserted, Deleted Or Updated) 
    IF EXISTS(SELECT * FROM inserted) AND NOT EXISTS (SELECT * FROM deleted) 
     SET @operation = 1 --Insert 
    ELSE 
     IF EXISTS(SELECT * FROM inserted) AND EXISTS (SELECT * FROM deleted) 
      SET @operation = 2 --update 
     ELSE 
      SET @operation = 3 -- DELETE 

    INSERT Requests 
    (
     Field1 
     , Field2 
     , ID 
     , TableName 
     , Operation 
     , TimeU 
     , Status 
    ) 
    SELECT 'Woof' 
     , 'Foof' 
     , i.ID 
     , 'Towns' 
     , @operation 
     , GETDATE() 
     , 0 
    FROM inserted i 
    LEFT JOIN Requests r on r.ID = i.ID 
     AND r.Operation = 3 
      OR (r.Operation = 1 and r.ID = i.ID) 
     AND r.Status = 0 
     AND r.TableName = 'Towns' 
    WHERE r.ID IS NULL 

    DELETE r 
    FROM Requests r 
    JOIN inserted i on i.Field1 = r.Field1 
     AND i.Field2 = r.Field2 
     AND i.ID = r.ID 
     AND i.Operation <> @operation 
    WHERE r.TableName = 'Towns' 
     AND r.Status = 0 
END 

В целом, я думаю, что триггеры следует избегать, но они имеют свое место. Когда триггеры подходят, я, как правило, не большой поклонник выполнения всех трех операций. Со временем это становится очень грязным, потому что вам всегда нужно делать разные логики для разных операций. Разделение их на три триггера делает этот случай намного менее болезненным для обслуживания.

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