没有触发器的外表更新时更新时间戳列

时间:2013-05-24 02:52:19

标签: sql-server tsql sql-server-2008-r2

我正在尝试在Parent表上设置Timestamp / Rowversion,以便在Child表更新时,Parent表行上的Timestamp会更改。

我不需要知道Child表中的行,只是根据父节点的特定行已经改变。

USE [Test]
GO
CREATE TABLE [dbo].[Clerk](
  [ID] [int] NOT NULL,
  [Name] [varchar](20) NOT NULL,
  [lastUpdate] [timestamp] NOT NULL,
 CONSTRAINT [PK_Clerk] PRIMARY KEY CLUSTERED 
(
  [ID] ASC
)
CREATE TABLE [dbo].[ClerkAddress](
  [ClerkID] [int] NOT NULL,
  [Address] [varchar](40) NOT NULL,
 CONSTRAINT [PK_ClerkAddress] PRIMARY KEY CLUSTERED 
(
  [ClerkID] ASC
)
ALTER TABLE [dbo].[ClerkAddress]  WITH CHECK ADD  CONSTRAINT [FK_ClerkAddress_Clerk] FOREIGN KEY([ClerkID])
REFERENCES [dbo].[Clerk] ([ID])
ON UPDATE CASCADE


insert into Clerk (ID, Name) values (1, 'Test1')
insert into Clerk (id, Name) values (2, 'Test2')

insert into ClerkAddress (ClerkID, Address) values (1, 'address1')
insert into ClerkAddress (ClerkID, Address) values (2, 'address2')

使用以下代码示例。

update ClerkAddress set Address = NEWID() where ClerkID = 2
--no change to Clerk when address changes 
select * from Clerk 
select * from ClerkAddress 

--Of course these update the lastUpdate in clerk
update Clerk set Name = 'test2' where ID = 2 
update Clerk set Name = name

这是否可能,或者我是否需要为更新制作触发器? (update clerk set name = name where id = ClerkID

1 个答案:

答案 0 :(得分:2)

您可以将其显示为使用视图更新父行 您需要向ClerkAddress添加rowversion列,然后

CREATE VIEW dbo.Clerk2
WITH SCHEMABINDING -- works for me on SQL Server 2012
AS
SELECT
    C.ID, C.Name, ISNULL(MAX(CA.lastUpdate), C.lastUpdate) AS lastupdate
FROM
    [dbo].[Clerk] C
    LEFT JOIN
    [dbo].[ClerkAddress] CA ON C.ID = CA.ClerkID
GROUP BY
    C.ID, C.Name, C.lastUpdate
GO
SELECT * FROM dbo.Clerk2;
GO
update ClerkAddress set Address = NEWID() where ClerkID = 2;
GO
SELECT * FROM dbo.Clerk2;
GO
update ClerkAddress set Address = NEWID() where ClerkID = 2;
GO
SELECT * FROM dbo.Clerk2;
GO

这使用了rowversion中的最高值,但保留了Clerk上的实际rowversion(客户端仍可用于乐观并发)

这是有效的,因为rowversion是数据库唯一的