Sql server SQL Server:删除字段后触发器不工作
--------已更新触发代码,请帮助----------- 我有一个触发器,当行被更新时,它会记录某些列上的任何更新。它工作得很好,直到我在表格中间删除了一个列。它现在只记录删除列之前的列,而不会记录删除列之后的任何列。我猜表中有某种排序列顺序?因此,当我删除一列时,它不会对列重新编号 为了演示正在发生的事情,假设我有这样的专栏: 字段1 字段2 字段3 字段4 然后,我在设计视图中打开了该表并删除了字段2,因此该表现在有: 字段1 字段3 字段4 在此之后,触发器仅捕获并记录Field1上的任何更新,而不是Field3和Field4。。。等等,这些都不起作用。这与更新的列有关,但在删除列后,我无法确定它是如何关闭的 知道发生了什么吗?我是否需要以某种方式重新编号列,以便触发器可以正常工作?提前谢谢 这是扳机。是的,这是一个大的,它工作得很好,但当我删除标题和ShippingAddressFlag之间的一列时。标题前的任何字段都有效,标题后的任何字段都无效,我认为它是关闭的,因为该字段已删除。也许与更新的索引有关,我不知道如何解决这个问题Sql server SQL Server:删除字段后触发器不工作,sql-server,Sql Server,--------已更新触发代码,请帮助----------- 我有一个触发器,当行被更新时,它会记录某些列上的任何更新。它工作得很好,直到我在表格中间删除了一个列。它现在只记录删除列之前的列,而不会记录删除列之后的任何列。我猜表中有某种排序列顺序?因此,当我删除一列时,它不会对列重新编号 为了演示正在发生的事情,假设我有这样的专栏: 字段1 字段2 字段3 字段4 然后,我在设计视图中打开了该表并删除了字段2,因此该表现在有: 字段1 字段3 字段4 在此之后,触发器仅捕获并记录Field1上的
USE [Apps]
GO
/****** Object: Trigger [dbo].[trigger_PurchaseRequestLog] Script Date: 11/01/2013 09:10:46 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[trigger_PurchaseRequestLog] ON [dbo].[ERP_PurchaseRequest] FOR UPDATE, DELETE
AS
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) ,
@TYPE CHAR(1) ,
@PKSelect VARCHAR(1000)
SELECT @TableName = 'ERP_PurchaseRequest'
-- 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'
-- Print 'Type: ' + @Type
-- 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 select for insert
SELECT @PKSelect = COALESCE(@PKSelect+'+','') + '''<' + COLUMN_NAME + '=''+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
-- Primary Col .............
DECLARE @PKCol as Varchar(200)
SELECT @PKCol = 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
-- Primary Key .............
DECLARE @PK as Varchar(200)
SELECT @PK = COALESCE(@PK+'+','') + '''' + '''+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
PRINT 'Prinary Key: ' + @PK
-- Testing get The Primary Key
Declare @UserID as VARCHAR(128)
--SET @UserID = RTRIM(LTrim(isnull((select CONVERT(VARCHAR(12),CONTEXT_INFO())), '-1'))) --(SELECT TrackID FROM [Tools].[dbo].[EnhanceTrackingNote] where NoteID = 54)
/* Converting from varbinary to INT) */
SET @UserID = isnull((CAST(REPLACE(CAST(CONTEXT_INFO() AS varchar(128)) COLLATE Latin1_General_100_BIN ,
0x00,
'') AS INT) ), '-1')
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
print 'Field: ' + cast(@FIELD as varchar(100)) + ' vs MaxField: ' + cast(@maxfield as varchar(100))
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
PRINT 'Field Position: ' + CAST(@FIELD AS VARCHAR(10))
SELECT @fieldname = COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @TableName AND ORDINAL_POSITION = @FIELD
PRINT 'FieldName: ' + @fieldname
SELECT @SQL = 'insert Audit (Type, TableName, PKCol, PK, FieldName, OldValue, NewValue, UpdateDate, DBUserName, UserID)'
SELECT @SQL = @SQL + ' select ''' + @TYPE + ''''
SELECT @SQL = @SQL + ',''' + @TableName + ''''
SELECT @SQL = @SQL + ',''' + @PKCol + ''''
SELECT @SQL = @SQL + ',' + @PK
SELECT @SQL = @SQL + ',''' + @fieldname + ''''
SELECT @SQL = @SQL + ',convert(varchar(1000),d.' + replace(@fieldname, '''', '') + ')'
SELECT @SQL = @SQL + ',convert(varchar(1000),i.' + replace(@fieldname, '''', '') + ')'
SELECT @SQL = @SQL + ',''' + @UpdateDate + ''''
SELECT @SQL = @SQL + ',''' + @UserName + ''''
SELECT @SQL = @SQL + ',''' + @UserID + ''''
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)'
--Print @SQL
--EXEC (@SQL)
PRINT cast( (SUBSTRING(COLUMNS_UPDATED(), @CHAR, 1) & @bit) as varchar(200)) + ' ---> ' + CAST(@FIELD AS VARCHAR(10)) + ' FieldName: ' + @fieldname
IF @fieldname <> 'CompleteNote' AND
@fieldname <> 'DateChangeReason' AND
@fieldname <> 'ActivityDescription'
BEGIN
-- Match the Update
--PRINT ('Match Update: ' + CAST(@CHAR AS varchar(2000)))
IF (SUBSTRING(COLUMNS_UPDATED(),@CHAR, 1) & @bit > 0) AND (@TYPE IN ('U'))
BEGIN
PRINT 'Matched U - Performing the update... '
IF (
(@TYPE IN ('U') and UPDATE(QuoteVerID)) OR
(@TYPE IN ('U') and UPDATE(Amount)) OR
(@TYPE IN ('U') and UPDATE(Title)) OR
(@TYPE IN ('U') and UPDATE(ShippingAddressFlag)) OR
(@TYPE IN ('U') and UPDATE(ShippingAddressComments)) OR
(@TYPE IN ('U') and UPDATE(ShippingContactFlag)) OR
(@TYPE IN ('U') and UPDATE(ShippingContactComments)) OR
(@TYPE IN ('U') and UPDATE(ShippingMethod)) OR
(@TYPE IN ('U') and UPDATE(ShippingMethodComments)) OR
(@TYPE IN ('U') and UPDATE(ShippingExpedite)) OR
(@TYPE IN ('U') and UPDATE(ShippingExpediteComments)) OR
(@TYPE IN ('U') and UPDATE(EndUserRequiredFlag)) OR
(@TYPE IN ('U') and UPDATE(EndUserRequiredContactID)) OR
(@TYPE IN ('U') and UPDATE(IntegrationFlag)) OR
(@TYPE IN ('U') and UPDATE(AdditionQuote)) OR
(@TYPE IN ('U') and UPDATE(AssignedTo)) OR
(@TYPE IN ('U') and UPDATE(Notes))
)
BEGIN
PRINT ' ---> Execute Update SQL'
PRINT @SQL
EXEC (@SQL)
END
END
END
-- Match the Delete and Insert
ELSE IF (@TYPE = 'D') OR (@TYPE = 'I')
BEGIN
--PRINT 'Matched D and I'
EXEC (@SQL)
END
END
如果您发布一些代码,这里会有更多的关注甚至答案。COLUMNS_UPDATED操作表中列的列索引-因此,是的,如果您删除一列,当然,您还必须在这里调整此模式,以适应新的现实,即列在表中的显示方式!如果没有触发代码,包括绑定详细信息的创建脚本,就没有机会获得答案…:很有可能简单地删除并重新创建触发器就可以解决问题。根据上面的说明,触发器只需要重新编译。