CTE в курсоре выдает ошибку "Соединение занято результатами для другой команды", а производная таблица - нет.
Недавно я столкнулся с ошибкой при извлечении из курсора запроса, который использовал CTE.
"[Microsoft] [родной клиент SQL Server 10.0] Соединение разорвано с результатами для другой команды"
Ошибка произошла на последующем курсоре, который выполняется на каждой итерации выборки.
Мне удалось устранить ошибку, заменив CTE производной таблицей.
Мне нужно знать, почему производная таблица работает нормально, в то время как CTE дает сбой, и если я сделал что-то не так в примере CTE.
Исходный запрос был относительно сложным, включал несколько объединений, но в основном сводился к следующему:
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