我有一个触发器来审核插入,删除和更新。为此,我已经修改了在线可用脚本。这些脚本无需任何修改即可很好地工作,但是对于业务需求,我进行了一些更改。对于我整个数据库中的9个表,此触发器具有自定义更改。触发器对于除1之外的所有8个表都运行良好。它给我发出的1个表仅适用于1列。
我的表包含以下列:
CREATE TABLE [d2c].[linkage_profile](
[linkage_profile_id] [int] IDENTITY(1,1) NOT NULL Primary Key,
[first_name] [nvarchar](250) NULL,
[last_name] [nvarchar](250) NULL,
[middle_name] [nvarchar](250) NULL,
[suffix] [nvarchar](50) NULL,
[is_pregnant] [bit] NULL,
[expected_date] [datetime2](7) NULL,
[user_id] [int] NOT NULL,
[is_grace_period] [bit] NOT NULL,
[closed_date] [datetime2](7) NULL,
[birth_gender_id] [int] NOT NULL,
[status_id] [int] NOT NULL,
[assigned_date] [datetime2](7) NULL,
[created_by] [nvarchar](50) NULL,
[date_created] [datetime2](7) NOT NULL,
[modified_by] [nvarchar](50) NULL,
[date_modified] [datetime2](7) NULL,
[state_no] [nvarchar](20) NULL,
[county_id] [int] NULL,
[area_name] [nvarchar](3) NULL,
[ehars_client_profile_id] [int] NULL,
[priority_id] [int] NULL,
[assigned_by] [nvarchar](50) NULL,
这是我正在使用的触发器:
Alter TRIGGER [d2c].[tr_linkage_profile] ON d2c.linkage_profile FOR INSERT, UPDATE, DELETE
AS
SET NOCOUNT ON
DECLARE @bit INT ,
@field INT ,
@fieldId INT ,
@maxfield INT ,
@char INT ,
@fieldname VARCHAR(128) ,
@FieldDisplayName VARCHAR(128),
@TableDisplayName VARCHAR(128),
@SchemaName VARCHAR(128) ,
@TableName VARCHAR(128) ,
@PKCols VARCHAR(1000) ,
@sql VARCHAR(5000),
@UpdateDate VARCHAR(21) ,
@UserName VARCHAR(128) ,
@Type CHAR(1) ,
@PKSelect VARCHAR(1000) ,
@linkageID VARCHAR(1000) ,
@FullTableName VARCHAR(256),
@oldvalue VARCHAR(1000),
@newvalue VARCHAR(1000),
@oldvalue1 VARCHAR(1000),
@newvalue1 VARCHAR(1000),
--@modified_by VARCHAR(20)='modified_by',
@isviewable char(1),
@next bit
SELECT @TableName = 'linkage_profile' , @schemaName = 'd2c'
SELECT @FullTableName = @SchemaName + '.' + @TableName
-- date and user
SELECT @UserName = SYSTEM_USER ,
@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 pk.TABLE_SCHEMA = @SchemaName
AND CONSTRAINT_TYPE = 'PRIMARY KEY'
AND c.TABLE_NAME = pk.TABLE_NAME
AND c.CONSTRAINT_NAME = pk.CONSTRAINT_NAME
AND c.CONSTRAINT_SCHEMA = pk.TABLE_SCHEMA
-- Get primary key select for insert
SELECT @PKSelect = COALESCE(@PKSelect+'+','') + '''' +
'''+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 pk.TABLE_SCHEMA = @SchemaName
AND CONSTRAINT_TYPE = 'PRIMARY KEY'
AND c.TABLE_NAME = pk.TABLE_NAME
AND c.CONSTRAINT_NAME = pk.CONSTRAINT_NAME
AND c.CONSTRAINT_SCHEMA = pk.TABLE_SCHEMA
-- Get client id select for insert
if @FullTableName <> 'd2c.ehars_client_profile'
BEGIN
SELECT @linkageID = COALESCE(@linkageID+'+','') + '''' +
'''+convert(varchar(100),coalesce(i.' + COLUMN_NAME +',d.' + COLUMN_NAME + '))+'''''
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE c
WHERE c.TABLE_NAME = @TableName
AND c.TABLE_SCHEMA = @SchemaName
AND c.COLUMN_NAME = 'linkage_profile_id'
END
if @FullTableName = 'd2c.ehars_client_profile'
SELECT @linkageID = 'NULL'
IF @PKCols IS NULL
BEGIN
RAISERROR('no PK on table %s', 16, -1, @FullTableName)
RETURN
END
---------------------Display value for table
SET @TableDisplayName = 'Linkage Profile Data'
--------------------------
SELECT @field = 0,
@maxfield = MAX(ORDINAL_POSITION)
FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @TableName AND TABLE_SCHEMA = @SchemaName
WHILE @field < @maxfield
BEGIN
SELECT @fieldname = COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @TableName
AND TABLE_SCHEMA = @SchemaName
AND ORDINAL_POSITION = @field
SELECT @fieldid = COLUMNPROPERTY(OBJECT_ID(@FullTableName), @fieldname, 'ColumnID')
SELECT @field = MIN(ORDINAL_POSITION)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @TableName
AND TABLE_SCHEMA = @SchemaName
AND ORDINAL_POSITION > @field
select @bit = (@fieldid - 1 )% 8 + 1
select @bit = power(2,@bit - 1)
select @char = ((@fieldid - 1) / 8) + 1
----
--select TABLE_NAME, COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME in ('barrier_client', 'client_attempt','disposition', 'ehars_client_profile', 'note_attachement', 'linkage_profile', 'provider_attempt', 'referral_client', 'result')
--------------display values for fields
SET @FieldDisplayName = CASE @fieldname --I have a lot of case statement here, removed to keep it short
WHEN 'assigned_by' THEN 'Assigned By'
WHEN 'assigned_date' THEN 'Assigned Date'
END
-- Managing Is viewable field for all types
select @isviewable = '0'
----------
if @type in('U')
begin
select @isviewable = '1'
end
-----------
if @type in('D')
if @fieldname in ('referral_id','other_desc','barrier_id')
Begin
select @IsViewable='1'
End
-----------
if @fieldname in ('created_by','date_created')
Begin
select @IsViewable='0'
End
-----------setting next at default 0
Select @next = 0
--------------------------------field specific values 5 Linkage Profile
if @fieldname = 'User_ID'
BEGIN
select @oldvalue =c.first_name from [d2c].[user] c inner join deleted d on d.User_ID = c.User_ID
select @oldvalue1 =c.last_name from [d2c].[user] c inner join deleted d on d.User_ID = c.User_ID
Select @oldvalue = CONCAT (@oldvalue , ' ', @oldvalue1)
if @oldvalue = 'd.expected_date ' set @oldvalue = 'NULL'
select @newvalue = c.first_name from [d2c].[user] c inner join inserted i on i.User_ID = c.User_ID
select @newvalue1 =c.last_name from [d2c].[user] c inner join inserted i on i.User_ID = c.User_ID
Select @newvalue = CONCAT (@newvalue , ' ', @newvalue1)
if @newvalue = 'i.expected_date ' set @newvalue = 'NULL'
Select @next = 1
end
if @fieldname = 'birth_gender_id'
BEGIN
select @oldvalue =c.name from lu.birth_gender c inner join deleted d on d.birth_gender_id = c.birth_gender_id
if @oldvalue = 'd.closed_date' set @oldvalue = 'NULL'
select @newvalue = c.name from lu.birth_gender c inner join inserted i on i.birth_gender_id = c.birth_gender_id
if @newvalue = 'i.closed_date' set @newvalue = 'NULL'
Select @next = 1
end
if @fieldname = 'Status_ID'
BEGIN
select @oldvalue =c.status_name from lu.status c inner join deleted d on d.Status_ID = c.Status_ID
if @oldvalue = 'd.closed_date' set @oldvalue = 'NULL'
select @newvalue = c.status_name from lu.status c inner join inserted i on i.Status_ID = c.Status_ID
if @newvalue = 'i.closed_date' set @newvalue = 'NULL'
Select @next = 1
end
if @fieldname = 'county_id'
BEGIN
select @oldvalue =c.name from lu.county c inner join deleted d on d.county_id = c.county_id
if @oldvalue = 'd.state_no' set @oldvalue = 'NULL'
select @newvalue = c.name from lu.county c inner join inserted i on i.county_id = c.county_id
if @newvalue = 'i.state_no' set @newvalue = 'NULL'
Select @next = 1
end
if @fieldname = 'priority_id'
BEGIN
select @oldvalue =c.priority_name from lu.priority c inner join deleted d on d.priority_id = c.priority_id
if @oldvalue = 'd.ehars_client_profile_id' set @oldvalue = 'NULL'
select @newvalue = c.priority_name from lu.priority c inner join inserted i on i.priority_id = c.priority_id
if @newvalue = 'i.ehars_client_profile_id' set @newvalue = 'NULL'
Select @next = 1
end
--------------------------------------------------------------------------running field specific value in insert
If @next = 1
if substring(COLUMNS_UPDATED(),@char, 1) & @bit > 0 or @Type in ('I','D')
print substring(COLUMNS_UPDATED(),@char, 1);
BEGIN
SELECT @sql = '
insert d2c.Audit_client_Data ( Type,TableSchema,TableName,tabledisplayname,fielddisplayname,
PK, linkage_profile_id,is_viewable,FieldName, OldValue, NewValue,
UpdateDate, UserName,Application)
select ''' + @Type + ''','''+ @SchemaName + ''',''' + @TableName + ''',''' + @TableDisplayName + '''
,''' + @FieldDisplayName + ''',' + @PKSelect + ',' + @linkageID + ', ' + @isviewable+'
,''' + @fieldname + ''''+ ', ''' +@oldvalue+''', ''' +@newvalue+''', ' + '''' + @UpdateDate + ''''+ '
,''' + @UserName + ''''+ ',''' + REPLACE(APP_NAME(), '''', '''''') + '''' +
' from #ins i full outer join #del d'+ @PKCols+ ' where i.' + @fieldname + ' <> d.' + @fieldname + ' or (i.' + @fieldname + ' is null and d.'+ @fieldname + ' is not null)' + ' or (i.' + @fieldname + ' is not null and d.' + @fieldname + ' is null)'
EXEC (@sql)
END
--------------------condition 1 change this for each trigger
if @next = 0
if @fieldname not in ('modified_by','date_modified')
if substring(COLUMNS_UPDATED(),@char, 1) & @bit > 0 or @Type in ('I','D')
BEGIN
select @oldvalue ='d.'+@fieldname
select @newvalue = 'i.'+@fieldname
SELECT @sql = '
insert d2c.Audit_client_Data ( Type,TableSchema,TableName,tabledisplayname,fielddisplayname,
PK, linkage_profile_id,is_viewable,FieldName, OldValue, NewValue,
UpdateDate, UserName,Application)
select ''' + @Type + ''','''+ @SchemaName + ''',''' + @TableName + ''',''' + @TableDisplayName + '''
,''' + @FieldDisplayName + ''',' + @PKSelect + ',' + @linkageID+ ', ' + @isviewable+'
,''' + @fieldname + ''''+ ', ' +@oldvalue+', ' +@newvalue+', ' + '''' + @UpdateDate + ''''+ '
,''' + @UserName + ''''+ ',''' + REPLACE(APP_NAME(), '''', '''''') + '''' +
' from #ins i full outer join #del d'+ @PKCols+ ' where i.' + @fieldname + ' <> d.' + @fieldname + ' or (i.' + @fieldname + ' is null and d.'+ @fieldname + ' is not null)' + ' or (i.' + @fieldname + ' is not null and d.' + @fieldname + ' is null)'
EXEC (@sql)
END
---------------------
END
当我更新,插入或删除所有列时,触发器将处理除最后一列Assigned_by以外的所有内容。我无法找出问题所在。它没有通过此代码
"if substring(COLUMNS_UPDATED(),@char, 1) & @bit > 0 or @Type in ('I','D')" which is at the very bottom. HELP!!!