我有一个关于MS SQL如何评估CTE内部函数的问题。一些搜索没有得出任何有关这个问题的结果,但我很抱歉,如果这是常识,我只是在曲线后面。这不会是第一次:-)评估SQL Server 2005中的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')
结果产生一列,一列表,包含3纳秒与碱型,其具有的值219935.
鉴于上述假设“INT”的SQL_VARIANT,是有意义(我,反正)该表达式的结果上述应该总是产生两包含一条记录的列表 - CustomerID和一个EmployeeID。 CustomerID应始终为int值219935,并且EmployeeID应为42或43.
但是,情况并非总是如此。有时我会得到预期的单一记录。其他时候,我得到两个记录(每个EmployeeID一个),还有一些我没有记录。但是,如果我将RandomizedCustomers CTE替换为真正的临时表,则问题完全消失。
每次我想我对这种行为有一个解释,结果是没有意义或不可能,所以我实际上无法解释为什么会发生这种情况。由于当我使用临时表替换CTE时,问题不会发生,因此我只能假定它与CTE内部的函数在连接到CTE期间进行评估。你们有没有任何理论?
我现在完全明白了。非常感谢您的帮助! – Jammer 2010-03-26 15:46:32