Spu*_*nik 4 sql-server snapshot-isolation sql-server-2019
我在这个问题上花了一些时间,终于有了一个重现该问题的示例(即使在所有 FK 上都有适当的非聚集索引)。
这是数据库操作的简要概述:
a) 更新/插入是在已提交读(快照)隔离下完成的。
b) 项目的删除是在快照隔离下完成的。
c) 所有FK都有索引。
清除过程会从数据库中删除旧的行。20-60 分钟后,下面的删除脚本将失败并出现快照错误。我被告知 FK 检查会恢复为读提交隔离,但即使这样也无法解释我们下面看到的内容。
重现步骤:
a) 创建数据库并确保快照选项为True。我们将该数据库称为 SnapshotTest。
b) 使用以下脚本创建数据库:
ALTER DATABASE [SnapshotTest] SET READ_COMMITTED_SNAPSHOT ON
GO
CREATE TYPE [dbo].[udtPPChildObject] AS TABLE(
[InsertionId] [bigint] NOT NULL,
[ChildInsertionId] [bigint] NOT NULL,
[PropertyMapNameId] [int] NOT NULL,
[UpdateId] [bigint] NULL,
PRIMARY KEY CLUSTERED
(
[ChildInsertionId] ASC
)WITH (IGNORE_DUP_KEY = OFF)
)
GO
CREATE TYPE [dbo].[udtPPChildObjectList] AS TABLE(
[InsertionId] [bigint] NOT NULL,
[ChildInsertionId] [bigint] NOT NULL,
[SortIndex] [int] NULL,
[UpdateId] [bigint] NULL,
[SortText] [nvarchar](260) NULL,
[RemovalThreshold] [bigint] NULL,
PRIMARY KEY CLUSTERED
(
[ChildInsertionId] ASC
)WITH (IGNORE_DUP_KEY = OFF)
)
GO
CREATE TYPE [dbo].[udtPPGuidList] AS TABLE(
[Guid] [uniqueidentifier] NOT NULL,
PRIMARY KEY CLUSTERED
(
[Guid] ASC
)WITH (IGNORE_DUP_KEY = OFF)
)
GO
CREATE TYPE [dbo].[udtPPObject] AS TABLE(
[InsertionId] [bigint] NOT NULL,
[ObjectId] [uniqueidentifier] NOT NULL,
[TypeNameId] [int] NOT NULL,
[UpdateId] [bigint] NULL,
[SourceInterpreterID] [uniqueidentifier] NULL,
[LevelID] [nvarchar](max) NULL,
[SearchParentInsertionID] [bigint] NULL,
PRIMARY KEY CLUSTERED
(
[InsertionId] ASC
)WITH (IGNORE_DUP_KEY = OFF)
)
GO
CREATE TYPE [dbo].[udtPPObjectBlobProperty] AS TABLE(
[InsertionId] [bigint] NOT NULL,
[PropertyMapNameId] [int] NOT NULL,
[BlobValue] [varbinary](max) NULL,
[UpdateId] [bigint] NULL,
PRIMARY KEY CLUSTERED
(
[InsertionId] ASC,
[PropertyMapNameId] ASC
)WITH (IGNORE_DUP_KEY = OFF)
)
GO
CREATE TYPE [dbo].[udtPPObjectProperty] AS TABLE(
[InsertionId] [bigint] NOT NULL,
[PropertyMapNameId] [int] NOT NULL,
[UpdateId] [bigint] NOT NULL,
[BitValue] [bit] NULL,
[UIDValue] [uniqueidentifier] NULL,
[FloatValue] [float] NULL,
[BigIntValue] [bigint] NULL,
[IntValue] [int] NULL,
[NVarCharValue] [nvarchar](max) NULL,
[SearchText] [nvarchar](max) NULL,
[TypeIndex] [tinyint] NOT NULL,
PRIMARY KEY CLUSTERED
(
[InsertionId] ASC,
[PropertyMapNameId] ASC
)WITH (IGNORE_DUP_KEY = OFF)
)
GO
CREATE TABLE [dbo].[tblPPObject](
[ObjectID] [uniqueidentifier] NOT NULL,
[UpdateTime] [datetime] NULL,
[InsertionID] [bigint] NOT NULL,
[SourceInterpreterID] [uniqueidentifier] NULL,
[LevelID] [nvarchar](260) NULL,
[UpdateID] [bigint] NULL,
[TypeNameID] [int] NOT NULL,
[SearchParentInsertionID] [bigint] NULL,
CONSTRAINT [PK_tblPPObject] PRIMARY KEY CLUSTERED
(
[InsertionID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 85, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[tblPPObjectBlobProperty](
[Value] [varbinary](max) NULL,
[UpdateTime] [datetime] NULL,
[InsertionID] [bigint] NOT NULL,
[UpdateID] [bigint] NULL,
[PropertyMapNameID] [int] NOT NULL,
CONSTRAINT [PK_tblPPObjectBlobProperty] PRIMARY KEY CLUSTERED
(
[InsertionID] ASC,
[PropertyMapNameID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 85, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
CREATE TABLE [dbo].[tblPPObjectChildObject](
[UpdateTime] [datetime] NULL,
[InsertionID] [bigint] NOT NULL,
[ChildInsertionID] [bigint] NOT NULL,
[UpdateID] [bigint] NULL,
[PropertyMapNameID] [int] NULL,
CONSTRAINT [PK_tblPPObjectChildObject] PRIMARY KEY CLUSTERED
(
[InsertionID] ASC,
[ChildInsertionID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 85, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[tblPPObjectChildObjectList](
[SortIndex] [int] NOT NULL,
[UpdateTime] [datetime] NULL,
[InsertionID] [bigint] NOT NULL,
[ChildInsertionID] [bigint] NOT NULL,
[SortText] [nvarchar](260) NULL,
[UpdateID] [bigint] NULL,
[RemovalThreshold] [bigint] NULL,
CONSTRAINT [PK_tblPPObjectChildObjectList] PRIMARY KEY CLUSTERED
(
[InsertionID] ASC,
[ChildInsertionID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 85, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[tblPPObjectProperty](
[UpdateTime] [datetime] NULL,
[InsertionID] [bigint] NOT NULL,
[BitValue] [bit] NULL,
[UIDValue] [uniqueidentifier] NULL,
[FloatValue] [float] NULL,
[BigIntValue] [bigint] NULL,
[IntValue] [int] NULL,
[NVarCharValue] [nvarchar](max) NULL,
[TypeIndex] [tinyint] NOT NULL,
[SearchText] [nvarchar](max) NULL,
[UpdateID] [bigint] NULL,
[PropertyMapNameID] [int] NOT NULL,
CONSTRAINT [PK_tblPPObjectProperty] PRIMARY KEY CLUSTERED
(
[InsertionID] ASC,
[PropertyMapNameID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 85, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
CREATE TABLE [dbo].[tblPPPropertyMapName](
[PropertyMapName] [varchar](max) NOT NULL,
[PropertyMapNameID] [int] IDENTITY(1,1) NOT NULL,
CONSTRAINT [PK_tblPPPropertyMapName] PRIMARY KEY CLUSTERED
(
[PropertyMapNameID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
CREATE TABLE [dbo].[tblPPRedundantObjects](
[InsertionID] [bigint] NOT NULL,
[UpdateTime] [datetime] NULL,
CONSTRAINT [PK_tblPPRedundantObjects] PRIMARY KEY CLUSTERED
(
[InsertionID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[tblPPTypeName](
[TypeName] [varchar](max) NOT NULL,
[TypeNameID] [int] IDENTITY(1,1) NOT NULL,
CONSTRAINT [PK_tblPPTypeName] PRIMARY KEY CLUSTERED
(
[TypeNameID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
CREATE NONCLUSTERED INDEX [IX_tblPPObject_LevelID_TypeNameID_InsertionID_INC_ObjectID] ON [dbo].[tblPPObject]
(
[LevelID] ASC,
[TypeNameID] ASC,
[InsertionID] ASC
)
INCLUDE([ObjectID]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 85, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
GO
CREATE UNIQUE NONCLUSTERED INDEX [IX_tblPPObject_ObjectID_INC_InsertionID_UpdateID_TypeNameID_SourceInterpreterID_LevelID] ON [dbo].[tblPPObject]
(
[ObjectID] ASC
)
INCLUDE([InsertionID],[UpdateID],[TypeNameID],[SourceInterpreterID],[LevelID]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 85, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [IX_tblPPObject_SearchParentInsertionID_SourceInterpreteID_InsertionID_INC_ObjectID_LevelID_UpdateID] ON [dbo].[tblPPObject]
(
[SearchParentInsertionID] ASC,
[SourceInterpreterID] ASC,
[InsertionID] ASC
)
INCLUDE([ObjectID],[LevelID],[UpdateID]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 85, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [IX_tblPPObjectBlobProperty_InsertionID] ON [dbo].[tblPPObjectBlobProperty]
(
[InsertionID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 85, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [IX_tblPPObjectChildObject_ChildInsertionID] ON [dbo].[tblPPObjectChildObject]
(
[ChildInsertionID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 85, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [IX_tblPPObjectChildObjectList_ChildInsertionID] ON [dbo].[tblPPObjectChildObjectList]
(
[ChildInsertionID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 85, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [IX_tblPPObjectProperty_InsertionID] ON [dbo].[tblPPObjectProperty]
(
[InsertionID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 85, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [IX_tblPPObjectProperty_InsertionID_TypeIndex_INC_SearchText] ON [dbo].[tblPPObjectProperty]
(
[InsertionID] ASC,
[TypeIndex] ASC
)
INCLUDE([SearchText])
WHERE ([TypeIndex]=(6))
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 85, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
GO
ALTER TABLE [dbo].[tblPPObjectProperty] ADD CONSTRAINT [DF_ObjectProperty_SearcText] DEFAULT (NULL) FOR [SearchText]
GO
ALTER TABLE [dbo].[tblPPObject] WITH CHECK ADD CONSTRAINT [FK_tblPPObject_tblPPTypeName] FOREIGN KEY([TypeNameID])
REFERENCES [dbo].[tblPPTypeName] ([TypeNameID])
GO
ALTER TABLE [dbo].[tblPPObject] CHECK CONSTRAINT [FK_tblPPObject_tblPPTypeName]
GO
ALTER TABLE [dbo].[tblPPObjectBlobProperty] WITH CHECK ADD CONSTRAINT [FK_tblPPObjectBlobProperty_tblPPObject] FOREIGN KEY([InsertionID])
REFERENCES [dbo].[tblPPObject] ([InsertionID])
GO
ALTER TABLE [dbo].[tblPPObjectBlobProperty] CHECK CONSTRAINT [FK_tblPPObjectBlobProperty_tblPPObject]
GO
ALTER TABLE [dbo].[tblPPObjectBlobProperty] WITH CHECK ADD CONSTRAINT [FK_tblPPObjectBlobProperty_tblPPPropertyMapName] FOREIGN KEY([PropertyMapNameID])
REFERENCES [dbo].[tblPPPropertyMapName] ([PropertyMapNameID])
GO
ALTER TABLE [dbo].[tblPPObjectBlobProperty] CHECK CONSTRAINT [FK_tblPPObjectBlobProperty_tblPPPropertyMapName]
GO
ALTER TABLE [dbo].[tblPPObjectChildObject] WITH CHECK ADD CONSTRAINT [FK_tblPPObjectChildObject_tblPPObject] FOREIGN KEY([ChildInsertionID])
REFERENCES [dbo].[tblPPObject] ([InsertionID])
GO
ALTER TABLE [dbo].[tblPPObjectChildObject] CHECK CONSTRAINT [FK_tblPPObjectChildObject_tblPPObject]
GO
ALTER TABLE [dbo].[tblPPObjectChildObject] WITH CHECK ADD CONSTRAINT [FK_tblPPObjectChildObject_tblPPPropertyMapName] FOREIGN KEY([PropertyMapNameID])
REFERENCES [dbo].[tblPPPropertyMapName] ([PropertyMapNameID])
GO
ALTER TABLE [dbo].[tblPPObjectChildObject] CHECK CONSTRAINT [FK_tblPPObjectChildObject_tblPPPropertyMapName]
GO
ALTER TABLE [dbo].[tblPPObjectChildObjectList] WITH CHECK ADD CONSTRAINT [FK_tblPPObjectChildObjectList_tblPPObject] FOREIGN KEY([ChildInsertionID])
REFERENCES [dbo].[tblPPObject] ([InsertionID])
GO
ALTER TABLE [dbo].[tblPPObjectChildObjectList] CHECK CONSTRAINT [FK_tblPPObjectChildObjectList_tblPPObject]
GO
ALTER TABLE [dbo].[tblPPObjectProperty] WITH CHECK ADD CONSTRAINT [FK_tblPPObjectProperty_tblPPObject] FOREIGN KEY([InsertionID])
REFERENCES [dbo].[tblPPObject] ([InsertionID])
GO
ALTER TABLE [dbo].[tblPPObjectProperty] CHECK CONSTRAINT [FK_tblPPObjectProperty_tblPPObject]
GO
ALTER TABLE [dbo].[tblPPObjectProperty] WITH CHECK ADD CONSTRAINT [FK_tblPPObjectProperty_tblPPPropertyMapName] FOREIGN KEY([PropertyMapNameID])
REFERENCES [dbo].[tblPPPropertyMapName] ([PropertyMapNameID])
GO
ALTER TABLE [dbo].[tblPPObjectProperty] CHECK CONSTRAINT [FK_tblPPObjectProperty_tblPPPropertyMapName]
GO
CREATE NONCLUSTERED INDEX [IX_tblPPObjectChildObject_UpdateID] ON [dbo].[tblPPObjectChildObject]
(
[UpdateID] ASC
)
INCLUDE([ChildInsertionID]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 85, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [IX_tblPPObjectChildObjectList_UpdateID] ON [dbo].[tblPPObjectChildObjectList]
(
[UpdateID] ASC
)
INCLUDE([ChildInsertionID]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 85, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
GO
CREATE procedure [dbo].[spMergePPObject]
(
@values dbo.udtPPObject readonly
)
as
begin
begin try
declare @updatetime datetime
set @updatetime = GetUTCDate()
update t
set t.UpdateTime = @updatetime, t.UpdateId = s.UpdateId, t.TypenameId = s.TypeNameId, t.SourceInterpreterID = s.SourceInterpreterID, t.LevelID = s.LevelID, t.SearchParentInsertionID = s.SearchParentInsertionID
from tblPPObject as t
join @values as s
on s.InsertionId = t.InsertionID and (s.UpdateID is not null)
insert into tblPPObject (InsertionId, ObjectId, TypeNameId, UpdateId, UpdateTime, SourceInterpreterID, LevelID, SearchParentInsertionID)
select s.InsertionId, s.ObjectId, s.TypeNameId, s.UpdateId, @updatetime, s.SourceInterpreterID, s.LevelID, s.SearchParentInsertionID
from @values as s
left join tblPPObject as t
on s.InsertionID = t.InsertionID
where t.InsertionID is null
end try
begin catch
declare @errormessage varchar(256)
select @errormessage = ERROR_MESSAGE()
raiserror('Error updating entries in the tblPPObject Table. %s', 16, 1, @errormessage)
end catch
end
GO
CREATE procedure [dbo].[spMergePPObjectBlobProperty]
(
@values dbo.udtPPObjectBlobProperty readonly
)
as
begin
begin try
declare @updatetime datetime
set @updatetime = GetUTCDate()
update t
set t.UpdateTime = @updatetime, t.[Value] = s.BlobValue, t.UpdateId = s.UpdateId
from tblPPObjectBlobProperty as t
join @values as s
on s.InsertionId = t.InsertionID and t.PropertyMapNameId = s.PropertyMapNameID
insert into tblPPObjectBlobProperty (PropertyMapNameId, Value, UpdateId, UpdateTime, InsertionId)
select s.PropertyMapNameId, s.BlobValue, s.UpdateId, @updatetime, s.InsertionId
from @values as s
left join tblPPObjectBlobProperty as t
on s.InsertionID = t.InsertionID and t.PropertyMapNameId = s.PropertyMapNameID
where t.InsertionID is null and t.PropertyMapNameID is null
end try
begin catch
declare @errormessage varchar(256)
select @errormessage = ERROR_MESSAGE()
raiserror('Error updating entries in the tblPPObjectBlobProperty Table. %s', 16, 1, @errormessage)
end catch
end
GO
create procedure [dbo].[spMergePPObjectChildObject]
(
@values dbo.udtPPChildObject readonly
)
as
begin
begin try
declare @updatetime datetime
set @updatetime = GetUTCDate()
update t
set t.UpdateID = s.UpdateID, t.UpdateTime = @updatetime
from tblPPObjectChildObject as t
join @values as s
on s.InsertionId = t.InsertionID and t.ChildInsertionId = t.ChildInsertionID
insert into tblPPObjectChildObject (InsertionID, ChildInsertionID, PropertyMapNameID, UpdateID, UpdateTime)
select s.InsertionID, s.ChildInsertionID, s.PropertyMapNameID, s.UpdateID, @updatetime
from @values as s
left join tblPPObjectChildObject as t
on s.InsertionId = t.InsertionID and s.ChildInsertionID = t.ChildInsertionID
where t.ChildInsertionID is null
end try
begin catch
declare @errormessage varchar(256)
select @errormessage = ERROR_MESSAGE()
raiserror('Error updating entries in the tblPPObjectChildObject Table. %s', 16, 1, @errormessage)
end catch
end
GO
create procedure [dbo].[spMergePPObjectChildObjectList]
(
@values dbo.udtPPChildObjectList readonly
)
as
begin
begin try
declare @updatetime datetime
set @updatetime = GetUTCDate()
update t
set t.UpdateID = isnull(s.UpdateID, t.UpdateID), t.UpdateTime = @updatetime, t.RemovalThreshold = isnull(s.RemovalThreshold, t.RemovalThreshold), t.SortIndex = isnull(s.SortIndex, t.SortIndex), t.SortText = isnull(s.SortText, t.SortText)
from tblPPObjectChildObjectList as t
join @values as s
on s.InsertionID = t.InsertionID and s.ChildInsertionId = t.ChildInsertionID
insert into tblPPObjectChildObjectList (InsertionID, ChildInsertionID, SortIndex, UpdateID, UpdateTime, SortText, RemovalThreshold)
select s.InsertionID, s.ChildInsertionID, isnull(s.SortIndex, -1), s.UpdateID, @updatetime, s.SortText, s.RemovalThreshold
from @values as s
left join tblPPObjectChildObjectList as t
on s.InsertionId = t.InsertionID and s.ChildInsertionID = t.ChildInsertionID
where t.ChildInsertionID is null
end try
begin catch
declare @errormessage varchar(256)
select @errormessage = ERROR_MESSAGE()
raiserror('Error updating entries in the tblPPObjectChildObjectList Table. %s', 16, 1, @errormessage)
end catch
end
GO
CREATE procedure [dbo].[spMergePPObjectProperty]
(
@values dbo.udtPPObjectProperty readonly
)
as
begin
begin try
declare @updatetime datetime
set @updatetime = GetUTCDate()
update t
set t.UpdateTime = @updatetime, t.BitValue = s.BitValue, t.UIDValue = s.UIDValue, t.FloatValue = s.FloatValue, t.IntValue = s.IntValue, t.NVarCharValue = s.NVarCharValue, t.BigIntValue = s.BigIntValue, t.UpdateId = s.UpdateId, t.TypeIndex = s.TypeIndex, t.SearchText = s.SearchText
from tblPPObjectProperty as t
join @values as s
on s.InsertionId = t.InsertionID and t.PropertyMapNameId = s.PropertyMapNameID
insert into tblPPObjectProperty (InsertionId, PropertyMapNameId, UpdateID, UpdateTime, BitValue, UIDValue, FloatValue, IntValue, NVarCharValue, BigIntValue, TypeIndex, SearchText)
select s.InsertionId, s.PropertyMapNameId, s.UpdateId, @updatetime, s.BitValue, s.UidValue, s.floatValue, s.IntValue, s.NVarCharValue, s.BigIntValue, s.TypeIndex, s.SearchText
from @values as s
left join tblPPObjectProperty as t
on s.InsertionID = t.InsertionID and t.PropertyMapNameId = s.PropertyMapNameID
where t.InsertionID is null and t.PropertyMapNameID is null
end try
begin catch
declare @errormessage varchar(256)
select @errormessage = ERROR_MESSAGE()
raiserror('Error updating entries in the tblPPObjectProperty Table. %s', 16, 1, @errormessage)
end catch
end
GO
create procedure [dbo].[spPurge](@modelinsertionid bigint)
as
begin
set deadlock_priority low
set nocount on
print 'Start Purge'
-- Work out what can be removed
begin transaction
declare @Redundant
删除执行计划显示带有完整扫描的合并连接,因此所有行都会被触及。罪魁祸首是dbo.spPurge过程中的表变量:
declare @RedundantInsertionIDs table (InsertionID bigint, UpdateTime DateTime)
Run Code Online (Sandbox Code Playgroud)
这缺少帮助优化删除查询的索引。我观察到表变量上的主键改进了计划,以便通过查找而不是扫描来访问目标表,只触及要删除的行而不是活动行。
declare @RedundantInsertionIDs table (InsertionID bigint primary key, UpdateTime DateTime);
Run Code Online (Sandbox Code Playgroud)
如果您仍然遇到问题,使用临时表而不是表变量可能会有所帮助。作为最后的手段,您还可以在清除过程中实施重试。