Dinamicamente trovando valori di colonna in un trigger INSERT da quando il nome di colonna è una variabile
-
06-09-2019 - |
Domanda
Ho un trigger che ottiene gli inserti e gli aggiornamenti per una vista. Ho bisogno di trovare le colonne che vengono modificati e ottenere il valore nella tabella corretta.
INSERT INTO TempTableAttr_Lot(ID, [% Num]) VALUES(3, 24.0)
Sto cercando di capire come, nel mio grilletto, per ottenere il valore di ID e [%] Num colonne. Il problema è che ci possono essere 32 diverse colonne impostate nell'inserto o aggiornamento, quindi voglio scorrere cerca di vedere se tale colonna è nella tabella 'inserita'.
Un problema è che se uso exec o eseguire, per costruire una query dinamica, inserita non è portata per questo.
La vista è dinamica che se si aggiungono attributi quindi la visualizzazione viene rigenerato mediante una procedura immagazzinata, quindi non possono assumere quale colonna nomi nella vista in qualsiasi momento, si può aumentare o diminuire.
Idealmente mi piacerebbe fare SET @Value = (SELECT i.[@Name] FROM inserted i)
Ma @Name non è un nome di colonna, ma una variabile nel mio grilletto, così quando ho provato
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))
questo non ha funzionato come inserito sembra non essere portata.
Per la prima @Name loop = 'ID' e per la seconda sarà 'Col2' che non è stato inserito, in modo che il valore di @Value dovrebbe essere nullo, e continuare a scorrere i possibili nomi di colonna finché io finitura, e il grilletto viene elaborato.
che io chiamo un grilletto, esso è definito come:
CREATE TRIGGER TempTableAttr_LotTrigger
ON TempTableAttr_Lot
INSTEAD OF UPDATE, INSERT
Sono test con un comando INSERT in questo momento. Mi rendo conto che quando si fa un aggiornamento posso avere bisogno di guardare il tavolo 'cancellato'.
UPDATE: Io parto dal presupposto solo una riga viene inserito in questo momento, per la mia prova, per vedere come arrivare a questo lavoro. Questo è per un database entità-attributo-valore, ma ho una visione che lo fa apparire relazionale. Quando si utilizza Integration Service, quando l'aggiornamento è in corso, eventuali inserti o aggiornamento alla vista chiameranno il grilletto. Sto solo cercando di capire come ottenere le informazioni che ho bisogno in modo da poter aggiornare la tabella corretta, con i valori corretti.
Soluzione
Per ottenere l'accesso al tabella inserita è possibile eseguire le seguenti operazioni.
SELECT * INTO #MYINSERTED FROM INSERTED
EXEC('SELECT * FROM #MYINSERTED')
DROP TABLE #MYINSERTED
Altri suggerimenti
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;