我有这样的结构在After Update触发器中使用动态列名
这两个查询通过此语句返回ColumnName
而不是Value
,
(select @Name from deleted)
(select @Name from inserted)
如何从中获取值然后存储到变量中?
ALTER TRIGGER [dbo].[afterUpdate_Project] ON [dbo].[Projects]
FOR UPDATE
as
begin
SET NOCOUNT ON;
DECLARE @ModifiedBy int = (select IsNULL(LastModifiedBy,0) from inserted)
DECLARE @Name varchar(MAX)
DECLARE my_Cursor CURSOR FOR
(
select C.name from sys.tables T
inner join sys.columns C on
T.object_id = C.object_id
where T.name = 'Projects'
)
OPEN my_Cursor;
FETCH NEXT FROM my_Cursor into @Name;
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @OldValue nvarchar(MAX) = (select @Name from deleted)
DECLARE @NewValue nvarchar(MAX) = (select @Name from inserted)
print @OldValue
print @NewValue
If (@OldValue <> @NewValue)
BEGIN
insert into EntityHistory
values(1, @Name, @OldValue, @NewValue, @ModifiedBy, GETDATE())
END
FETCH NEXT FROM my_Cursor into @Name;
END
CLOSE my_Cursor; DEALLOCATE my_Cursor;
END
答案 0 :(得分:1)
最后,我能够为您的问题找到解决方案。它涉及临时表。不建议过度使用临时表,但我找不到更好的解决方案。
以下是我创建的ALTER TRIGGER
脚本,它非常适合我的桌面。
ALTER TRIGGER [dbo].[afterUpdate_Project] ON [dbo].[Projects]
FOR UPDATE
AS
BEGIN
SET NOCOUNT ON;
DECLARE @ModifiedBy NVARCHAR(255) = (SELECT IsNULL(UserId,0) FROM inserted)
DECLARE @queryForInserted NVARCHAR(255)
DECLARE @queryForDeleted NVARCHAR(255)
DECLARE @Name varchar(MAX)
DECLARE my_Cursor CURSOR FOR
(
SELECT C.name FROM sys.objects T
INNER JOIN sys.columns C ON
T.object_id = C.object_id
WHERE T.name = 'Projects'
)
--Creating Temp table for storing single value for each of the column during iteration.
IF OBJECT_ID('tempdb..#tmpInsertedSingleValue') IS NULL CREATE TABLE #tmpInsertedSingleValue(InsertedValue NVARCHAR(MAX))
IF OBJECT_ID('tempdb..#tmpDeletedSingleValue') IS NULL CREATE TABLE #tmpDeletedSingleValue(DeletedValue NVARCHAR(MAX))
--Creating temp tables and populating them with data from 'inserted' and 'deleted'
SELECT TOP 1 * INTO #tmpInserted FROM inserted
SELECT TOP 1 * INTO #tmpDeleted FROM deleted
OPEN my_Cursor;
FETCH NEXT FROM my_Cursor into @Name;
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT @Name
-- Creating dynamic sql to select single column value from temp table.
SET @queryForDeleted = 'SELECT ' + @Name + ' FROM #tmpDeleted'
SET @queryForInserted = 'SELECT ' + @Name + ' FROM #tmpInserted'
-- Executing dynamic sql to populabe single column value to other temp table.
INSERT INTO #tmpDeletedSingleValue EXECUTE (@queryForDeleted)
INSERT INTO #tmpInsertedSingleValue EXECUTE (@queryForInserted)
-- Selecting single value in to variables.
DECLARE @OldValue NVARCHAR(MAX) = (SELECT TOP 1 * FROM #tmpDeletedSingleValue)
DECLARE @NewValue NVARCHAR(MAX) = (SELECT TOP 1 * FROM #tmpInsertedSingleValue)
PRINT @OldValue
PRINT @NewValue
IF (@OldValue <> @NewValue)
BEGIN
INSERT INTO EntityHistory
VALUES (1, @Name, @OldValue, @NewValue, @ModifiedBy, GETDATE())
END
--Clearing SingleValue temp tables after every iteration
DELETE FROM #tmpDeletedSingleValue
DELETE FROM #tmpInsertedSingleValue
FETCH NEXT FROM my_Cursor into @Name;
END
CLOSE my_Cursor; DEALLOCATE my_Cursor;
-- Clearing temp tables after looping thru all the columns
DELETE FROM #tmpDeleted
DELETE FROM #tmpInserted
END
这可以解决您的问题。