2017-10-27 6 views
0

私はemp_id、name、age、dobなど100の列を持つEmployeesテーブルを2つ持っています。もう1つはEmployees_auditです。 3列emp_id、updated_column、updated_time。私は更新されたemp_idと更新された列の名前を私に与えるafter updateトリガが必要です。前もって感謝します。更新された列名を私に与えるafter updateトリガーが必要です

サンプルデータ:Employees_auditで

Table Employees: 
---------- 
Emp_id|name|age|dob|.... 
1  abc 29 1991-10-28 

Table Employees_audit 
---------- 
Emp_id|updated_column|updated_time 

サンプル出力:

Emp_id|updated_column|updated_time 
1  dob   2017-10-27 8:40:57 
+0

あなたはここで答えを期待していますか?私たちはここで細部に何もない。情報がないと、あなたは確かにしっかりとした反応を得られないでしょう。ここから始めましょう。 http://spaghettidba.com/2015/04/24/how-to-post-at-sql-question-on-a-public-forum/ –

+0

これは決して楽しくはありませんが、効率的にやりたいのであれば。あなたの自由に使えるツールは、['COLUMNS_UPDATED'](https://docs.microsoft.com/sql/t-sql/functions/columns-updated-transact-sql)と[' UPDATE'](https:// docs Microsoft SQL/tql/functions/update-trigger-functions-transact-sql)を使用していますが、100列の場合は、トリガー本体(またはトリガー内の動的SQL)を生成する動的SQLが必要です。使用可能な場合は、[データ取り込みの変更](https://docs.microsoft.com/sql/relational-databases/track-changes/track-data-changes-sql-server)の使用を検討してください。 –

+0

答えを受け入れましたが、データキャプチャはエクスプレス版で利用できません – user3484775

答えて

0

のMyDataテーブル、あなたが引き金をしたい、PKを必要とします。

CREATE TABLE [dbo].[Audit](
[AuditID] [int] IDENTITY(1,1) NOT NULL, 
[Type] [char](1) NULL, 
[TableName] [varchar](128) NULL, 
[PrimaryKeyField] [varchar](1000) NULL, 
[PrimaryKeyValue] [varchar](1000) NULL, 
[FieldName] [varchar](128) NULL, 
[OldValue] [varchar](max) NULL, 
[NewValue] [varchar](max) NULL, 
[UpdateDate] [datetime] NULL DEFAULT (getdate()), 
[UserName] [varchar](128) NULL, 
[HostName] [varchar](100) NULL 
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] 

GO 
CREATE TRIGGER [dbo].[MyTable_ChangeTracking] on [dbo].[MyTable] for insert, update, delete 
as 
SET NOCOUNT ON 

declare @bit int , 
@field int , 
@maxfield int , 
@char int , 
@fieldname varchar(128) , 
@TableName varchar(128) , 
@PKCols varchar(1000) , 
@sql varchar(2000), 
@UpdateDate varchar(21) , 
@UserName varchar(128) , 
@HostName varchar(100), 
@Type char(1) , 
@PKFieldSelect varchar(1000), 
@PKValueSelect varchar(1000) 

select @TableName = 'MyTable' 

-- date and user 
select @UserName = system_user , @HostName = Host_Name(), 
@UpdateDate = convert(varchar(8), getdate(), 112) + ' ' + convert(varchar(12), getdate(), 114) 
-- Action 
if exists (select * from inserted) 
if exists (select * from deleted) 
select @Type = 'U' 
else 
select @Type = 'I' 
else 
select @Type = 'D' 
-- get list of columns 
select * into #ins from inserted 
select * into #del from deleted 
-- Get primary key columns for full outer join 
select @PKCols = coalesce(@PKCols + ' and', ' on') + ' i.[' + c.COLUMN_NAME + '] = d.[' + c.COLUMN_NAME+']' 
from INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk , 
INFORMATION_SCHEMA.KEY_COLUMN_USAGE c 
where pk.TABLE_NAME = @TableName 
and CONSTRAINT_TYPE = 'PRIMARY KEY' 
and c.TABLE_NAME = pk.TABLE_NAME 
and c.CONSTRAINT_NAME = pk.CONSTRAINT_NAME 
-- Get primary key fields select for insert 
select @PKFieldSelect = coalesce(@PKFieldSelect+'+','') + '''[' + COLUMN_NAME + ']''' 
from INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk , 
INFORMATION_SCHEMA.KEY_COLUMN_USAGE c 
where pk.TABLE_NAME = @TableName 
and CONSTRAINT_TYPE = 'PRIMARY KEY' 
and c.TABLE_NAME = pk.TABLE_NAME 
and c.CONSTRAINT_NAME = pk.CONSTRAINT_NAME 
select @PKValueSelect = coalesce(@PKValueSelect+'+','') + 'convert(varchar(100), coalesce(i.[' + COLUMN_NAME + '],d.[' + COLUMN_NAME + ']))' 
from INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk , 
INFORMATION_SCHEMA.KEY_COLUMN_USAGE c 
where pk.TABLE_NAME = @TableName 
and CONSTRAINT_TYPE = 'PRIMARY KEY' 
and c.TABLE_NAME = pk.TABLE_NAME 
and c.CONSTRAINT_NAME = pk.CONSTRAINT_NAME 
if @PKCols is null 
begin 
raiserror('no PK on table %s', 16, -1, @TableName) 
return 
end 
select @field = 0, @maxfield = max(ORDINAL_POSITION) from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = @TableName 
while @field < @maxfield 
begin 
select @field = min(ORDINAL_POSITION) from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = @TableName and ORDINAL_POSITION > @field 
select @bit = (@field - 1)% 8 + 1 
select @bit = power(2,@bit - 1) 
select @char = ((@field - 1)/8) + 1 
if substring(COLUMNS_UPDATED(),@char, 1) & @bit > 0 or @Type in ('I','D') 
begin 
select @fieldname = COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = @TableName and ORDINAL_POSITION = @field 
select @sql = 'insert Audit (Type, TableName, PrimaryKeyField, PrimaryKeyValue, FieldName, OldValue, NewValue, UpdateDate, UserName, HostName)' 
select @sql = @sql + ' select ''' + @Type + '''' 
select @sql = @sql + ',''' + @TableName + '''' 
select @sql = @sql + ',' + @PKFieldSelect 
select @sql = @sql + ',' + @PKValueSelect 
select @sql = @sql + ',''' + @fieldname + '''' 
select @sql = @sql + ',convert(varchar(1000),d.[' + @fieldname + '])' 
select @sql = @sql + ',convert(varchar(1000),i.[' + @fieldname + '])' 
select @sql = @sql + ',''' + @UpdateDate + '''' 
select @sql = @sql + ',''' + @UserName + '''' 
select @sql = @sql + ',''' + @HostName + '''' 
select @sql = @sql + ' from #ins i full outer join #del d' 
select @sql = @sql + @PKCols 
select @sql = @sql + ' where i.[' + @fieldname + '] <> d.[' + @fieldname+']' 
select @sql = @sql + ' or (i.[' + @fieldname + '] is null and d.[' + @fieldname + '] is not null)' 
select @sql = @sql + ' or (i.[' + @fieldname + '] is not null and d.[' + @fieldname + '] is null)' 
exec (@sql) 
end 
end 

GO 
+0

はい、主キー制約があり、emp_idです。こんにちは – user3484775

+0

ありがとうございました。私の答えを受け入れることができますか?どうも! –

関連する問題