2012-01-19 94 views
2

我發現這個迭代遍歷表的SQL函數,它發現ParentID代碼有效,除非我在其中放入where子句不適用於新創建的列。如果我不使用where子句,它會生成Expr1作爲樹的根,這是我想要的,但我不能在其上添加條件。'Where'表達式中的列名無效

有人可以幫我解決這個問題嗎?

ALTER FUNCTION dbo.fn_Root 
(
    @PostID int 
) 
RETURNS int 
AS 
BEGIN 
DECLARE @R int 

SELECT @R = CASE WHEN ParentPostID = 0 THEN PostID 
       ELSE dbo.fn_Root(ParentPostID) 
      END 
     FROM Post 
     WHERE PostID = @PostID 

RETURN @R 
END 


SELECT PostID, Title, dbo.fn_Root(PostID) AS Expr1 
FROM Post WHERE Expr1 = 5 

回答

2

另一種可能的解決方法:你可以再次把WHERE子句中的計算值:

SELECT PostID, Title, dbo.fn_Root(PostID) AS Expr1 
FROM Post 
WHERE dbo.fn_Root(PostID) = 5 
+0

謝謝你回答 – ONYX

+0

這是否評估函數兩次?它取決於該函數是否在SQL中被標記爲確定性的,還是以某種方式將其緩存到輸出的每一行? – jklemmack

3

您無法直接在SQL Server中的WHERE子句中引用計算/計算列別名。然而,一個平凡的解決方法是換行的聲明,把你WHERE條款在外面,指的是計算列:

SELECT * FROM (
    SELECT PostID, Title, dbo.fn_Root(PostID) AS Expr1 
    FROM Post) 
WHERE Expr1 = 5 
+0

「您不能直接在SQL Server的WHERE子句中引用計算/計算列」。該陳述不正確(請參閱@ChristianSpecht答案)。你不能做的是引用WHERE子句中的列別名。 – 2012-01-19 23:35:05

+0

謝謝你爲我今天學到的東西乾杯 – ONYX