0
Sr. ID   FName    LName    Mark
1   P1   amar     ranjan   100
2   P2   sameer   kumar    200
3   P1   amar     ranjan   200

在这里,我更新了Mark列的第一行。

在对单行的每次更新时,我正在创建具有更新值的新行(参见第 3 行)。是否可以获取表中已更新的列名?

4

3 回答 3

1

由于您使用的是 SQL Server 2008,因此您可以使用该OUTPUT子句来获取更新的数据。就像是:

UPDATE TableName
  SET Sr = 'foo',
      ID    = someid,
      FName = 'bar',
      LName = 'other foo',
      Mark  = someid
OUTPUT
  inserted.FName,
  deleted.FName AS oldFName,
  inserted.FName AS newFName
WHERE SR = 1; -- for mark;

但是,如果您需要将它插入到另一个表History中,您可以创建一个AFTER UPDATETRIGGER通过更新的数据更新历史表的数据,例如:

USE DatabaseName;
GO
IF OBJECT_ID ('Sch.TableNameTrigger', 'TR') IS NOT NULL
   DROP TRIGGER Sch.TableNameTrigger;
GO
CREATE TRIGGER Sch.TableNameTrigger
ON FirstTable
AFTER UPDATE
AS 
    INSERT INTO HistoryTable
    SELECT * FROM DELETED
GO

SQL 小提琴演示

于 2012-11-12T13:30:19.540 回答
1

我以 Mahmoud Gamal 的回答和 SQL Fiddle 演示为起点。

您需要的是可能的,但是如果您有权访问更新过程,我建议您在任何将更改直接保存在表中的存储过程中管理更新。

如果你需要一个触发器,这样的东西可以工作,但正如你所看到的,它有它自己的缺点:两个临时表,因为范围和一个游标。

它基本上每次都会为每一列生成一个检查,并将一列的新旧值插入历史表中。

(也建议将 ID 列更改为 Primary Key 和 Identity)

我还做了一个SQL FIDDLE演示

CREATE TABLE TableName (Sr INT, ID VARCHAR(10), FName VARCHAR(50),
LName VARCHAR(50), Mark VARCHAR(50));

CREATE TABLE HistoryTable (ID VARCHAR(10), ColumnName VARCHAR(50),
PrevValue VARCHAR(50), NewValue VARCHAR(50));



INSERT INTO TableName VALUES
(1, 'P1', 'amar', 'ranjan' , 100),
(2, 'P2', 'sameer', 'kumar', 200),
(3, 'P1', 'amar', 'ranjan', 200);



CREATE TRIGGER TableNameTrigger
ON TableName
AFTER UPDATE
AS 


SELECT * INTO #Deleted  FROM Deleted 
SELECT * INTO #Inserted FROM Inserted  

DECLARE @ColName varchar(64)
DECLARE columnCursor CURSOR FOR
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'TableName' AND TABLE_SCHEMA='dbo'

OPEN columnCursor

FETCH NEXT FROM columnCursor INTO @ColName

WHILE (@@FETCH_STATUS <> -1)
BEGIN


EXEC(N'INSERT INTO HistoryTable 
     SELECT Deleted.Sr, ''' + @ColName + ''', Deleted.'+ @ColName + ',' + 'Inserted.' + @ColName +' 
     FROM #Deleted Deleted
     INNER JOIN #Inserted Inserted ON Inserted.Sr = Deleted.Sr
     WHERE Deleted.'+ @ColName + ' != Inserted.' + @ColName)




FETCH NEXT FROM columnCursor INTO @ColName

END


DROP TABLE #Deleted 
DROP TABLE #Inserted 

CLOSE columnCursor

DEALLOCATE columnCursor

GO
于 2012-11-12T15:04:42.623 回答
0

我想说,创建另一个名为 history 的表并存储更新的内容和时间。

在一个表中制作重复条目是糟糕的设计。另外我不确定您如何处理重复条目?

假设您想打印数据以P1了解您的处理方式?


编辑 1

在我的一个网站中,客户想知道谁添加/编辑/删除了什么以及何时。所以我创建了一个名为 HISTORY 的新表,一旦添加/编辑/删除完成,我就会在该表中输入它。为一个用户创建多行是糟糕的设计。

于 2012-11-12T13:31:52.310 回答