2012-12-02 51 views
1

更換ColdFusion的遞歸函數調用我有一個名爲dbo.Node表:與公用表表達式(CTE)

NodeID  int 
ParentNodeID int 
Title 

以下功能顯示

<cffunction name="getNodePath" returnType="string"> 
    <cfargument name="NodeID" required="false" default=""> 

    <cfset var qryNode = ""> 

    <cfif NOT isNumeric(arguments.nodeID)> 
     <cfreturn ""> 
    </cfif> 

    <cfquery name="qryNode" cachedWithin="#CreateTimeSpan(0,0,1,0)#"> 
     SELECT ParentNodeID, Title 
     FROM dbo.Node WITH (NOLOCK) 
     WHERE NodeID = <cfqueryparam CFSQLType="CF_SQL_INTEGER" value="#arguments.NodeID#"> 
    </cfquery>  

    <cfreturn getNodePath(qryNode.ParentNodeID) & qryNode.Title & " &raquo; "> 
</cffunction> 

該代碼使用cacheWithin層次因爲已知許多相同的父路徑將被調用。平均而言,這會從原始頁面調用約20次。總的來說,由於查詢的遞歸性質,它被稱爲100次。而且這個函數返回一個字符串。這意味着格式不在視圖中。

有沒有辦法用CTE代替它?

回答

0

與CTE

版本

<cfset var qryNode = ""> 
<cfset var lstPath = ""> 

<cfif NOT isNumeric(arguments.nodeID)> 
    <cfreturn QueryNew("Empty")> 
</cfif> 

<cfquery name="qryNode"> 
    WITH Family AS ( 

     SELECT N.NodeID, ISNULL(N.ParentNodeID, '') AS ParentNodeID, Slug, N.Title, N.Kind, 0 AS Depth, N.CreateDate 
     FROM dbo.vwNode N WITH (NOLOCK) 
     WHERE NodeID = TRY_CONVERT(int, <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#arguments.NodeID#">) 

     UNION ALL 

     SELECT N2.NodeID, ISNULL(N2.ParentNodeID, '') AS ParentNodeID, N2.Slug, N2.Title, N2.Kind, Depth + 1, N2.CreateDate 
     FROM dbo.vwNode N2 WITH (NOLOCK) 

     INNER JOIN Family 
     ON  Family.ParentNodeID = N2.NodeID 
     WHERE PrimaryRecord = 0 
     ) 


    SELECT NodeID, ParentNodeID, Slug, Title, Kind, Depth, CreateDate 
    FROM Family 
    ORDER BY Depth DESC 
</cfquery>  

<cfreturn qryNode> 

隨着語句來替換遞歸調用。這個功能現在只能調用大約20次。沒有必要緩存結果,因爲它們不會被重用。該函數現在返回一個查詢。格式化現在在它所屬的視圖上