Tsql 需要比较两行中的差异吗?
我需要将两行相互比较,然后将更改后的字段写入表中 我的桌子:Tsql 需要比较两行中的差异吗?,tsql,stored-procedures,iteration,Tsql,Stored Procedures,Iteration,我需要将两行相互比较,然后将更改后的字段写入表中 我的桌子: CREATE TABLE dbo.tUserChanges ( cID int IDENTITY (1,1), cChangeDate DateTime, cValueChanged varchar(30), cPreviousValue bit, cCurrentValue bit ) 在我的C程序中,当对用户进行更改时,需要更新用户表 这是通过存储过程完成的: CREATE PROCEDURE [dbo].[UUser]
CREATE TABLE dbo.tUserChanges
(
cID int IDENTITY (1,1),
cChangeDate DateTime,
cValueChanged varchar(30),
cPreviousValue bit,
cCurrentValue bit
)
在我的C程序中,当对用户进行更改时,需要更新用户表
这是通过存储过程完成的:
CREATE PROCEDURE [dbo].[UUser]
(
@User as varchar(15),
@UCode AS int,
@UName AS varchar(30),
@UID AS varchar(10),
@UPassword AS varchar(15),
@UPMaintenance as bit,
@UClient as bit,
@UFinancial as bit,
@UViewReceiptImage bit,
@UViewPayrollData bit
)
AS
BEGIN
UPDATE tUsers
SET
UName = @UName,
UID = @UID,
UPassword = @UPassword, UPMaintenance = @UPMaintenance,
UClient = @UClient,
UFinancial = @UFinancial,
UViewReceiptImage = @UViewReceiptImage,
UViewPayrollData = @UViewPayrollData
WHERE UCode = @UCode
END
tUser表中有更多的值,但为了保持排序,我删除了一些值
所以我需要做的是在更新tUsers表之前创建一个temp表,以便在更新完成后比较这两行,然后将发生的更改更正到新表中
我已经尝试过这个方法,但我知道有更好的方法,而且它也不能提供所需的结果:
declare @i int
set @i = 0
declare @ColumnCount int
set @ColumnCount = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = @UID)
declare @ColumnName varchar(30)
set @ColumnName = (select column_name from information_schema.columns where table_name = 'tUsers' and ordinal_position = 14)
select UActivateLoan from tusers
while (@ColumnCount < @i)
Begin
if((select @ColumnName from tUsers where UID = @UID)
<> (select @ColumnName from #myTemp where UID = @UID))
Begin
Insert into tUserChanges
Values(GETDATE(),(select column_name from information_schema.columns where table_name = 'tUsers' and ordinal_position = 14),
(select(select column_name from information_schema.columns where table_name = 'tUsers' and ordinal_position = 14) from #myTemp where UID = @UID),
(select(select column_name from information_schema.columns where table_name = 'tUsers' and ordinal_position = 14) from tUsers where UID = @UID))
END
set @i = @i + 1
End
我不确定我是否需要在这里使用光标,或者我可以做些什么来获得结果?
任何帮助都将不胜感激。最好使用FOR UPDATE触发器 创建触发器,这是一种特殊的存储过程 当用户尝试指定的操作时自动执行 指定表上的数据修改语句。Microsoft®SQL 服务器™ 允许为任何给定插入创建多个触发器, 更新或删除语句 编辑 使用动态SQL,将类似于
CREATE TRIGGER dbo.tUser_AfterUpdate ON dbo.tUsers FOR UPDATE AS
BEGIN
DECLARE @Columns TABLE (name sysname)
DECLARE @ColumnName sysname
DECLARE @Statement VARCHAR(MAX)
INSERT INTO @Columns
SELECT name
FROM sys.columns
WHERE OBJECT_NAME(OBJECT_ID) = 'tUsers'
WHILE EXISTS (SELECT * FROM @Columns)
BEGIN
SELECT TOP 1 @ColumnName = name FROM @Columns
DELETE FROM @Columns WHERE name = @ColumnName
SET @Statement =
'IF UPDATE(' + @ColumnName + ') THEN '
+ 'INSERT INTO tUserChanges '
+ 'SELECT GETDATE() '
+ ' , (SELECT ' + @ColumnName + 'FROM DELETED) -- Old Value'
+ ' , (SELECT ' + @ColumnName + 'FROM INSERTED) -- New Value'
EXEC (@Statement)
END
END
SQL不会神奇地将字符串或变量解释为名称。如果您从tUsers中选择@ColumnName,其中UID=@UID,您的意思是选择@ColumnName变量的值,而不是从表中检索名为@ColumnName的列是的,我知道这一点,但我将其作为示例发布,因为我不知道该怎么做,所以我必须对表中的所有字段进行更新。在我看来,表中有216个字段,您有两个选择。1.复制/粘贴insert语句216次,更改列。2.使用动态sql。在这种情况下,我对这两种解决方案的感觉都很复杂。正确地复制/粘贴要容易得多,但是动态SQL较短,向基表添加列会自动覆盖。您将如何执行动态SQLoption@user1171437-我添加了一个可能的示例,但请确保对其进行广泛测试。我还没有验证这种构造是否可以在更新触发器中实现。非常感谢您的帮助,我非常感谢
CREATE TRIGGER dbo.tUser_AfterUpdate ON dbo.tUsers FOR UPDATE AS
BEGIN
DECLARE @Columns TABLE (name sysname)
DECLARE @ColumnName sysname
DECLARE @Statement VARCHAR(MAX)
INSERT INTO @Columns
SELECT name
FROM sys.columns
WHERE OBJECT_NAME(OBJECT_ID) = 'tUsers'
WHILE EXISTS (SELECT * FROM @Columns)
BEGIN
SELECT TOP 1 @ColumnName = name FROM @Columns
DELETE FROM @Columns WHERE name = @ColumnName
SET @Statement =
'IF UPDATE(' + @ColumnName + ') THEN '
+ 'INSERT INTO tUserChanges '
+ 'SELECT GETDATE() '
+ ' , (SELECT ' + @ColumnName + 'FROM DELETED) -- Old Value'
+ ' , (SELECT ' + @ColumnName + 'FROM INSERTED) -- New Value'
EXEC (@Statement)
END
END