0

我正在尝试在父表上设置时间戳/行版本,以便当子表更新时,父表行上的时间戳会更改。

我不需要知道 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)

4

1 回答 1

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 是数据库唯一的

于 2013-05-24T07:49:55.960 回答