我最近在从使用 CTE 的查询上的游标中获取时遇到了错误。
“[Microsoft][SQL Server native Client 10.0]Connection is bust with results for another command”
该错误发生在在每次提取迭代中执行的后续游标上。
我能够通过用派生表替换 CTE 来解决错误。
我需要知道为什么派生表工作正常,而 CTE 失败,以及我在 CTE 示例中是否做错了什么。
原来的查询比较复杂,涉及到多个join,但基本上有以下几种:
WITH cteResults AS (
SELECT Account.Id AS AccountId
FROM Accounts AS Account
WHERE Account.Number = '12345'
UNION
SELECT SubAccount.Id
FROM SubAccounts AS SubAccount
WHERE SubAccount.Number = '12345')
SELECT
Invoice.Value AS InvoiceValue,
CASE
WHEN Representative.Sequence IS NOT NULL THEN THEN Representative.Name
ELSE Account.OwnerName
END AS InvoiceName
FROM cteResults
INNER JOIN Invoices AS Invoice ON
Invoice.AccountId = cteResults.AccountId
LEFT OUTER JOIN Accounts AS Account ON
Account.Id = Invoice.AccountId
LEFT OUTER JOIN AccountRepresentatives AS Representative ON
Representative.Id = Invoices.AccountRepresentativeId
有问题的代码将使用上述语句循环遍历游标,并且对于 FETCH 的每次迭代,它将执行第二个游标:
FOREACH InvoicesCursor INTO InvoiceResults.*
OPEN FormattingRulesCursor
FETCH FormattingRulesCursor into FormattingRules.*
// Error appears here
CLOSE FormattingRulesCursor
END FOREACH
在 FOREACH 语句期间从应用程序打开的任何游标都会失败,并出现我上面提到的错误。
但是,如果我删除 CTE 并使用派生表,我不会收到错误并且一切正常。
SELECT
Invoice.Value AS InvoiceValue,
CASE
WHEN Representative.Sequence IS NOT NULL THEN THEN Representative.Name
ELSE Account.OwnerName
END AS InvoiceName
FROM (SELECT Account.Id AS AccountId
FROM Accounts AS Account
WHERE Account.Number = '12345'
UNION
SELECT SubAccount.Id
FROM SubAccounts AS SubAccount
WHERE SubAccount.Number = '12345') AS cteResults
INNER JOIN Invoices AS Invoice ON
Invoice.AccountId = cteResults.AccountId
LEFT OUTER JOIN Accounts AS Account ON
Account.Id = Invoice.AccountId
LEFT OUTER JOIN AccountRepresentatives AS Representative ON
Representative.Id = Invoices.AccountRepresentativeId