У меня вопрос о том, как MS SQL оценивает функции внутри CTE. Несколько поисков не привели к каким-либо результатам, связанным с этой проблемой, но я извиняюсь, если это общеизвестно, и я просто отстаю от кривой. Это было бы не в первый раз :-)Оценка CTE в SQL Server 2005
Этот запрос является упрощенной (и, очевидно, менее динамичной) версией того, что я на самом деле делаю, но у нее есть проблема, с которой я столкнулся. Это выглядит следующим образом:
CREATE TABLE #EmployeePool(EmployeeID int, EmployeeRank int);
INSERT INTO #EmployeePool(EmployeeID, EmployeeRank)
SELECT 42, 1
UNION ALL
SELECT 43, 2;
DECLARE @NumEmployees int;
SELECT @NumEmployees = COUNT(*) FROM #EmployeePool;
WITH RandomizedCustomers AS (
SELECT CAST(c.Criteria AS int) AS CustomerID,
dbo.fnUtil_Random(@NumEmployees) AS RandomRank
FROM dbo.fnUtil_ParseCriteria(@CustomerIDs, 'int') c)
SELECT rc.CustomerID,
ep.EmployeeID
FROM RandomizedCustomers rc
JOIN #EmployeePool ep ON ep.EmployeeRank = rc.RandomRank;
DROP TABLE #EmployeePool;
можно предположить о всех казнях выше следующее:
Результат
dbo.fnUtil_Random()
всегда является INT значение больше нуля и меньше или равно аргумент передан. Поскольку он вызывается выше с@NumEmployees
, который имеет значение 2, эта функция всегда равна 1 или 2.Результат
dbo.fnUtil_ParseCriteria(@CustomerIDs, 'int')
создает таблицу с одним столбцом, одну строку, Н. С. sql_variant с базовым типом «межд», который имеет значение 219935.
Учитывая приведенное выше допущение, что имеет смысл (для меня, во всяком случае), что результат выражения выше всегда должен производить два -колоночная таблица, содержащая одну запись - CustomerID и EmployeeID. Идентификатор клиента всегда должен быть значением int 219935, а EmployeeID должен быть либо 42, либо 43.
Однако это не всегда так. Иногда я получаю ожидаемую единую запись. В других случаях я получаю две записи (по одному для каждого EmployeeID), а третьи - у меня нет записей. Однако, если я заменил RandomizedCustomers CTE на истинную временную таблицу, проблема полностью исчезнет.
Каждый раз, когда я думаю, что у меня есть объяснение этого поведения, он не имеет смысла или невозможен, поэтому я не могу объяснить, почему это произойдет. Поскольку проблема не возникает, когда я заменяю CTE на временную таблицу, я могу только предположить, что она имеет какое-то отношение к функциям внутри CTE, которые оцениваются во время присоединений к этому CTE. Есть ли у вас какие-либо теории?
Я полностью понимаю сейчас. Большое спасибо за Вашу помощь! – Jammer