Динамический поиск значений столбцов в триггере из INSERT, когда имя столбца является переменной - PullRequest
1 голос
/ 02 июня 2009

У меня есть триггер, который получает вставки и обновления для представления. Мне нужно найти столбцы, которые изменяются и получить значение в правильной таблице.

INSERT INTO TempTableAttr_Lot(ID, [% Num]) VALUES(3, 24.0)

Я пытаюсь выяснить, как в моем триггере получить значение столбца ID и [% Num]. Проблема в том, что во вставке или обновлении может быть установлено 32 разных столбца, поэтому я хочу просмотреть список, чтобы увидеть, находится ли этот столбец в таблице «вставок».

Одна проблема заключается в том, что, если я использую exec или execute, для построения динамического запроса, вставленный объект не входит в сферу действия.

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

В идеале я хотел бы сделать SET @Value = (SELECT i.[@Name] FROM inserted i) Но @Name - это не имя столбца, а переменная в моем триггере, поэтому при попытке

DECLARE @ValueTable TABLE ( value sql_variant)
INSERT INTO @ValueTable EXECUTE('SELECT i.[' + @Name + '] FROM inserted i')
SET @Value = CONVERT(nvarchar(128), (SELECT DISTINCT * FROM @ValueTable))

это не сработало, так как вставленный элемент не находится в области видимости.

Для первого цикла @Name = 'ID', а для второго это будет 'Col2', который не был вставлен, поэтому значение @Value должно быть нулевым, и я продолжаю циклически перебирать возможные имена столбцов до тех пор, пока финиш, и триггер обработан.

Я называю это триггером, он определяется как:

CREATE TRIGGER TempTableAttr_LotTrigger 
ON  TempTableAttr_Lot 
INSTEAD OF UPDATE, INSERT

Я сейчас тестирую с помощью команды INSERT. Я понимаю, что при обновлении мне может понадобиться посмотреть на «удаленную» таблицу.

ОБНОВЛЕНИЕ: я предполагаю, что в данный момент вставляется только одна строка для моего теста, чтобы увидеть, как заставить это работать. Это для базы данных атрибут-сущность, но у меня есть представление, которое делает его реляционным. При использовании службы интеграции, когда происходит обновление, любые вставки или обновления представления будут вызывать триггер. Я просто пытаюсь понять, как получить необходимую мне информацию, чтобы я мог обновить правильную таблицу с правильными значениями.

Ответы [ 2 ]

3 голосов
/ 02 июня 2009

Чтобы получить доступ к таблице INSERTED, вы можете сделать следующее.

SELECT * INTO #MYINSERTED FROM INSERTED

EXEC('SELECT * FROM #MYINSERTED')

DROP TABLE #MYINSERTED
0 голосов
/ 07 июня 2012
CREATE TRIGGER  triggerRowLog_tblMember 
--After INSERT  
ON dbo.tblMember
 AFTER UPDATE
--for EACH ROW
As
BEGIN

DECLARE @temptblCategory TABLE ( 
        idx smallint Primary Key IDENTITY(1,1)
        , CategoryID int
        , CategoryName nvarchar(100)
    )
    declare @i int
    set @i = 1
    declare @catcount int 
    set @catcount = 0
    Select @catcount=  Count(*) from tblCategoryMst Where Tag = 'A' or Tag = 'L'  and Active =1
    declare @CatName nvarchar(100)
    declare @CatID int
    declare @ValueCompare nvarchar(100)
    declare @PrevValueCompare nvarchar(100)
if(@catcount > 0)
begin
INSERT @temptblCategory 
    SELECT distinct CategoryID, CategoryName FROM tblCategoryMst  Where (Tag = 'A' or Tag = 'L' )and (TableName = 'Transactions' or TableName ='tblMember')  and Active =1
    While @i <= @catcount
        Begin


            set @CatName = (SELECT CategoryName FROM @temptblCategory WHERE idx = @i)
            set @CatID = (SELECT CategoryID FROM @temptblCategory WHERE idx = @i)

            if(@CatName = 'Form')
            Begin
                set @CatName = @CatName + 'Member'
            End
            else if(@CatName = 'Type')
            Begin
                set @CatName = 'Membership' + @CatName 
            End
            else if(@CatName = 'Address')
            Begin
                set @CatName = 'Cor' + @CatName 
            End

            declare @Query nvarchar(4000)
            SELECT * INTO #MYInserted FROM Inserted
            SELECT * INTO #MYDeleted FROM Deleted
            set @Query ='(Select @PrevValueCompare = ' + @CatName+' from #MYDeleted )'
            exec sp_executesql @Query ,N'@PrevValueCompare nvarchar(50) output', @PrevValueCompare output
            set @Query ='(Select @ValueCompare = ' + @CatName+' from #MYInserted )'
            exec sp_executesql @Query ,N'@ValueCompare nvarchar(50) output', @ValueCompare output

            DROP TABLE #MYInserted
            DROP TABLE #MYDeleted

            if( @ValueCompare <> 'no compare' and @ValueCompare  <>  @PrevValueCompare)
            Begin
                INSERT INTO dbo.tblLogMst(ID,IDOf,CategoryID, PreviousData, ChangedData,
                    ExchangeCode,CreatedBy,CreatedIP )
                      SELECT i.MemberID,'MS',@CatID, @PrevValueCompare, @ValueCompare ,
                    i.ExchangeCode,i.UpdatedBy,i.UpdatedIP
                      FROM Inserted i
                      INNER JOIN Deleted d ON i.MemberID = d.MemberID
            End
        set @i =  Convert(int,@i) + Convert(int,1)
        End
    end
END;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...