У меня есть вопрос о том, как MS SQL оценивает функции внутри CTE. Несколько поисков не дали никаких результатов, связанных с этой проблемой, но я прошу прощения, если это общеизвестно, и я просто за кривой. Это был бы не первый раз: -)
Этот запрос является упрощенной (и, очевидно, менее динамичной) версией того, что я на самом деле делаю, но он показывает проблему, с которой я сталкиваюсь. Это выглядит так:
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 с базовым типом 'int' со значением 219935.
Учитывая вышеизложенные предположения, имеет смысл (во всяком случае, для меня), что результат вышеприведенного выражения всегда должен создавать таблицу из двух столбцов, содержащую одну запись - CustomerID и EmployeeID. CustomerID должен всегда иметь значение int 219935, а EmployeeID должно быть 42 или 43.
Однако это не всегда так. Иногда я получаю ожидаемую единственную запись. В других случаях я получаю две записи (по одной для каждого EmployeeID), а в другие я не получаю никаких записей. Однако, если я заменю RandomizedCustomers CTE на истинную временную таблицу, проблема полностью исчезнет.
Каждый раз, когда я думаю, что у меня есть объяснение этому поведению, оказывается, что оно не имеет смысла или невозможно, поэтому я буквально не могу объяснить, почему это произойдет. Так как проблема не возникает, когда я заменяю CTE временной таблицей, я могу только предположить, что она как-то связана с функциями внутри CTE, которые оцениваются при соединениях с этим CTE. У кого-нибудь из вас есть теории?