跟踪sql行中的更改以进行更新

时间:2013-09-30 12:56:38

标签: mysql sql sql-server timestamp unix-timestamp

我有一个java程序来更新SQL表(id, name, status)。整个表使用相同的数据或一些更改的数据进行更新。如何跟踪行是否与更新前相同或者有一些修改过的数据? id将始终相同,只是名称上的小错字。如果名称被修改,我只想检查下一次更新。在这种情况下,状态字段应从“相同”更改为“已修改”。时间戳会解决我的问题吗?请帮忙。

4 个答案:

答案 0 :(得分:1)

1 - 如果您希望审核该表(插入,更新,删除),请查看我如何防止不需要的交易幻灯片w /代码 - http://craftydba.com/?page_id=880

最后查看代码!

填充审计表的触发器可以保存来自多个表的信息,因为数据保存为XML。因此,您可以根据需要取消删除。它跟踪谁和改变了什么。

2 - 如果您永远不会清除审计表中的数据,为什么不将该行标记为已删除但仍保留该行?

许多系统如人们使用有效的约会来显示记录是否不再有效。在BI世界中,这被称为类型2维表(缓慢变化的维度)。

请参阅数据仓库研究所文章。 http://www.bidw.org/datawarehousing/scd-type-2/ 每条记录都有一个开始和结束日期。所有活动记录的结束日期均为空。

3 - Micorsoft SQL Server引入了更改数据捕获功能。虽然事后跟踪了LOG阅读器的数据变化,但它缺少像是谁以及做出改变的事情。

同样,所有上述解决方案都有效。我偏爱我的解决方案!

此致

约翰

Crafty DBA

-- 
-- 7 - Auditing data changes (table for DML trigger)
-- 


-- Delete existing table
IF OBJECT_ID('[AUDIT].[LOG_TABLE_CHANGES]') IS NOT NULL 
  DROP TABLE [AUDIT].[LOG_TABLE_CHANGES]
GO


-- Add the table
CREATE TABLE [AUDIT].[LOG_TABLE_CHANGES]
(
  [CHG_ID] [numeric](18, 0) IDENTITY(1,1) NOT NULL,
  [CHG_DATE] [datetime] NOT NULL,
  [CHG_TYPE] [varchar](20) NOT NULL,
  [CHG_BY] [nvarchar](256) NOT NULL,
  [APP_NAME] [nvarchar](128) NOT NULL,
  [HOST_NAME] [nvarchar](128) NOT NULL,
  [SCHEMA_NAME] [sysname] NOT NULL,
  [OBJECT_NAME] [sysname] NOT NULL,
  [XML_RECSET] [xml] NULL,
 CONSTRAINT [PK_LTC_CHG_ID] PRIMARY KEY CLUSTERED ([CHG_ID] ASC)
) ON [PRIMARY]
GO

-- Add defaults for key information
ALTER TABLE [AUDIT].[LOG_TABLE_CHANGES] ADD CONSTRAINT [DF_LTC_CHG_DATE] DEFAULT (getdate()) FOR [CHG_DATE];
ALTER TABLE [AUDIT].[LOG_TABLE_CHANGES] ADD CONSTRAINT [DF_LTC_CHG_TYPE] DEFAULT ('') FOR [CHG_TYPE];
ALTER TABLE [AUDIT].[LOG_TABLE_CHANGES] ADD CONSTRAINT [DF_LTC_CHG_BY] DEFAULT (coalesce(suser_sname(),'?')) FOR [CHG_BY];
ALTER TABLE [AUDIT].[LOG_TABLE_CHANGES] ADD CONSTRAINT [DF_LTC_APP_NAME] DEFAULT (coalesce(app_name(),'?')) FOR [APP_NAME];
ALTER TABLE [AUDIT].[LOG_TABLE_CHANGES] ADD CONSTRAINT [DF_LTC_HOST_NAME] DEFAULT (coalesce(host_name(),'?')) FOR [HOST_NAME];
GO



--
--  8 - Make DML trigger to capture changes
--


-- Delete existing trigger
IF OBJECT_ID('[ACTIVE].[TRG_FLUID_DATA]') IS NOT NULL 
  DROP TRIGGER [ACTIVE].[TRG_FLUID_DATA]
GO

-- Add trigger to log all changes
CREATE TRIGGER [ACTIVE].[TRG_FLUID_DATA] ON [ACTIVE].[CARS_BY_COUNTRY]
  FOR INSERT, UPDATE, DELETE AS
BEGIN

  -- Detect inserts
  IF EXISTS (select * from inserted) AND NOT EXISTS (select * from deleted)
  BEGIN
    INSERT [AUDIT].[LOG_TABLE_CHANGES] ([CHG_TYPE], [SCHEMA_NAME], [OBJECT_NAME], [XML_RECSET])
    SELECT 'INSERT', '[ACTIVE]', '[CARS_BY_COUNTRY]', (SELECT * FROM inserted as Record for xml auto, elements , root('RecordSet'), type)
    RETURN;
  END

  -- Detect deletes
  IF EXISTS (select * from deleted) AND NOT EXISTS (select * from inserted)
  BEGIN
    INSERT [AUDIT].[LOG_TABLE_CHANGES] ([CHG_TYPE], [SCHEMA_NAME], [OBJECT_NAME], [XML_RECSET])
    SELECT 'DELETE', '[ACTIVE]', '[CARS_BY_COUNTRY]', (SELECT * FROM deleted as Record for xml auto, elements , root('RecordSet'), type)
    RETURN;
  END

  -- Update inserts
  IF EXISTS (select * from inserted) AND EXISTS (select * from deleted)
  BEGIN
    INSERT [AUDIT].[LOG_TABLE_CHANGES] ([CHG_TYPE], [SCHEMA_NAME], [OBJECT_NAME], [XML_RECSET])
    SELECT 'UPDATE', '[ACTIVE]', '[CARS_BY_COUNTRY]', (SELECT * FROM deleted as Record for xml auto, elements , root('RecordSet'), type)
    RETURN;
  END

END;
GO

答案 1 :(得分:0)

SQL Server没有在表级别进行版本控制。如果要跟踪两个字段之间的差异,则至少有两个选项:

  1. 从Java应用程序进行控制 - 在更新方法中进行更新前检查。
  2. 从SQL Server控制 - 再次写入触发器以进行更新前检查
  3. 您还可以创建免费字段,其中将保留版本号

答案 2 :(得分:0)

是的,你可以使用时间戳。 通过使用时间戳,您可以找到表中的最新条目,并通过在查询中使用按时间戳排序,您可以获取最新信息并根据相应的值设置状态

答案 3 :(得分:0)

这取决于您需要多少信息。如果你关心的是记录是否曾被修改过,你可以使用created_when和updated_when字段。如果后者大于前者,则会更新。

如果您想知道哪些字段已更新,则必须记录更改。细节取决于您的要求。如果您需要记录更改,触发器是最好的方法。