SQL查询奇怪的行为:在执行两个变量时永远不会完成

时间:2017-03-22 16:16:11

标签: sql sql-server

我一直在对SQL存储过程进行故障排除,该过程一直挂起并且没有完成执行。我将问题简化为声明的两个变量。下面显示的SQL查询是存储过程的片段。以下是我执行的测试用例场景。

  • 将WHERE子句中的@startver和@endver替换为56并且它有效。查询在不到一秒的时间内完成。
  • 在WHERE子句中用@starver替换@endver并且它有效。查询在不到一秒的时间内完成。
  • 在WHERE子句中用@endver替换@starver并且它有效。查询在不到一秒的时间内完成。

当两个变量放在一起时,它不起作用。它一直显示

  

执行查询......

有谁知道为什么会这样?我怎样才能解决这个问题?我无法调试这个,因为SQL实例在AWS中,我没有sysadmin帐户。

A a = db.A.Where(x => x.ID == 1);
List<B> listB = new List<B>();
foreach(var b in a.B)
{
    listB.Add(db.B.Where(x => x.ID == b.ID);
}

foreach(var b in listB)
{
    a.B.Remove(b);
}

//Populate a.B with new B's as per requirement

db.Entry(a).State = EntityState.Modified;
db.SaveChanges();

更新:在使用正确的内部联接重新编写查询后,我仍然遇到相同的错误。

DECLARE @startver int = 56, @endver int = 56

SELECT 
    Z_Prodver.ProdverID ProdverID,
    Prod.ProdName,
    Z_Prodver.Releasedver,
    Z_DNameLen.Z_DName Z_DName,
    Z_DItemOffsets.Offset DItemOffset,
    Z_DNameLen.Offset DNameIndex,
    (Z_FormType.storagesize * M.ASize * DItem.ASize * 
        CASE DType.grouped
            WHEN 0 THEN 1
            ELSE 8
        END
    ) AllocationSize,
    H_NAME()
FROM
    Z_Prodver,
    Prod,
    DItem,
    DType,
    M,
    Z_DNameLen,
    Z_DItemOffsets,
    ProdPerM,
    Z_ProdSupport,
    Form,
    Z_FormType
WHERE
    DItem.ProdverID >= @startver
    AND DItem.ProdverID <= @endver
    AND DItem.DName = Z_DNameLen.DName
    AND DType.DTypeName = DItem.DTypeName
    AND DType.ProdverID = DItem.ProdverID
    AND M.MName = DItem.MName
    AND M.ProdverID = DItem.ProdverID
    AND M.MName = ProdPerM.MName
    AND M.ProdverID = ProdPerM.ProdverID
    AND ProdPerM.ProdverID = Z_Prodver.ProdverID
    AND Z_DItemOffsets.ProdverID = Z_Prodver.ProdverID
    AND Prod.ProdName = ProdperM.ProdName
    AND Z_DItemOffsets.DName = DItem.DName
    AND Form.FormName = DItem.FormName
    AND Z_FormType.FormTypeName = Form.FormTypeName
    AND Form.ProdverID = DItem.ProdverID
    AND Z_DItemOffsets.HostName = H_NAME()
    AND Z_ProdSupport.ProdverID = M.ProdverID
    AND Z_ProdSupport.ProdName= Prod.ProdName
    AND Z_ProdSupport.PCSupport = 1

1 个答案:

答案 0 :(得分:3)

DItem.ProdverID >= @startver AND DItem.ProdverID <= @endver

@startver@endver相同时,这意味着所有 ProdverID

这个查询的一个丑陋的工作是:

and 1 = case when @startver = @endver and DItem.ProdverID <> @startver 
        then 0 
      else 1 
      end

但是整个查询需要使用正确的连接进行重写,并且使用上面的解决方法将从option (recompile)或转换为使用动态sql大大受益。

参考: