【发布时间】:2019-09-08 06:39:46
【问题描述】:
使用下面显示的代码,我遇到了事务死锁。 Split 函数接受一个字符串并将列表拆分为一个表,我在该表上进行选择。我有READ UNCOMMITTED。我是否应该将Split 放入临时表中,然后对其进行查询?
ALTER PROCEDURE [Revisions]
@ScheduleRevisionIds NVARCHAR(MAX) = NULL
AS
BEGIN
SET NOCOUNT ON;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
IF(@ScheduleRevisionIds IS NOT NULL)
BEGIN
-- GET SCHEDULE REVISIONS
SELECT esr.Id
INTO #TempScheduleRevisions
FROM Revision esr
WHERE EXISTS (SELECT items
FROM dbo.Split(@ScheduleRevisionIds, ',')
WHERE esr.Id = items)
功能
ALTER FUNCTION [Split](@String varchar(MAX), @Delimiter char(1))
returns @temptable TABLE (items varchar(MAX))
as
begin
declare @idx int
declare @slice varchar(MAX)
select @idx = 1
if len(@String)<1 or @String is null return
while @idx!= 0
begin
set @idx = charindex(@Delimiter,@String)
if @idx!=0
set @slice = left(@String,@idx - 1)
else
set @slice = @String
if(len(@slice)>0)
insert into @temptable(Items) values(@slice)
SET @String = right(@String, LEN(@String) - @idx)
IF LEN(@String) = 0 BREAK
END
RETURN
END
【问题讨论】:
-
你能显示
split()函数的代码吗? -
假设您有一个合理编写的拆分函数,我看不出在发布的一小段代码中如何发生死锁。您将需要更深入地研究竞争资源访问的连接所执行的代码。至少您需要确定争用的资源。
-
(1)您使用哪个版本的 SQL Server?从 2016 年起,您可以使用内置函数 STRING_SPLIT。(2)为什么需要这个拆分功能?您用“,”分割字符串以扫描结果并检查是否存在特定文本......为什么不简单地检查文本是否存在于原始字符串中?在字符串的开头添加“,”并使用类似where CHARINDEX(","+esr.Id+",", ","+@ScheduleRevisionIds+",") > 0的方式检查字符串 (","+@ScheduleRevisionIds+",") 中是否存在 (","+esr.Id+",") -
如果您可以发布表格 DD+DML+ 预期结果,那么我们可能能够快速提供完整的解决方案/演示
-
这里没有足够的信息可以说明,因为肯定有其他原因导致死锁。我发现的一件事是 Select INTO 会导致锁定,而 CREATE TABLE 后跟 INSERT 则不会。你可以试试。
标签: sql sql-server stored-procedures stored-functions database-deadlocks