열 이름이 변수 일 때 인서트에서 트리거에서 열 값을 동적으로 찾습니다.
-
06-09-2019 - |
문제
보기에 인서트와 업데이트를 얻는 트리거가 있습니다. 수정중인 열을 찾아 올바른 테이블에 값을 가져와야합니다.
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의 값은 null이어야하며, 완료하고 끝날 때까지 가능한 열 이름을 계속해서 루프해야합니다. 트리거가 처리됩니다.
나는 그것을 트리거라고 부릅니다. 그것은 다음과 같이 정의됩니다.
CREATE TRIGGER TempTableAttr_LotTrigger
ON TempTableAttr_Lot
INSTEAD OF UPDATE, INSERT
현재 삽입 명령으로 테스트하고 있습니다. 업데이트를 할 때 '삭제 된'테이블을 살펴 봐야 할 수도 있습니다.
업데이트 : 테스트를 위해이 작업을 수행하는 방법을 확인하기 위해 현재 하나의 행만 삽입되고 있다고 가정합니다. 이것은 엔터티 부사장 데이터베이스를위한 것이지만 관계형으로 보이게하는 견해가 있습니다. Integration Service를 사용할 때 업데이트가 진행될 때 뷰에 대한 인서트 또는 업데이트는 트리거를 호출합니다. 필요한 정보를 얻는 방법을 이해하려고 노력하고있어 올바른 값으로 올바른 테이블을 업데이트 할 수 있습니다.
해결책
삽입 된 테이블에 액세스하려면 다음을 수행 할 수 있습니다.
SELECT * INTO #MYINSERTED FROM INSERTED
EXEC('SELECT * FROM #MYINSERTED')
DROP TABLE #MYINSERTED
다른 팁
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;