【问题标题】:SQL Server function inside a Select statement and transaction deadlockSelect 语句中的 SQL Server 函数和事务死锁
【发布时间】: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+",") &gt; 0 的方式检查字符串 (","+@ScheduleRevisionIds+",") 中是否存在 (","+esr.Id+",")
  • 如果您可以发布表格 DD+DML+ 预期结果,那么我们可能能够快速提供完整的解决方案/演示
  • 这里没有足够的信息可以说明,因为肯定有其他原因导致死锁。我发现的一件事是 Select INTO 会导致锁定,而 CREATE TABLE 后跟 INSERT 则不会。你可以试试。

标签: sql sql-server stored-procedures stored-functions database-deadlocks


【解决方案1】:

我没有任何具体的说法可以说明您的查询的任何部分都会导致事务死锁。但是,我认为您可以使用我觉得更简单的 JOIN,并且可能会让您摆脱麻烦的死锁。所以,试试这个:

 SELECT esr.Id INTO #TempScheduleRevisions
 FROM 
 Revision esr
 INNER JOIN
 dbo.Split(@ScheduleRevisionIds, ',') sri
 ON
 sri.items = esr.id

【讨论】:

    猜你喜欢
    • 2016-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-08
    • 1970-01-01
    • 1970-01-01
    • 2015-10-30
    相关资源
    最近更新 更多