我有一個關於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