用公用表表达式(CTE)替换ColdFusion递归函数调用

时间:2012-12-02 19:35:38

标签: sql-server recursion coldfusion common-table-expression

我有一个名为dbo.Node的表:

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替换它?

1 个答案:

答案 0 :(得分: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>

With 语句取代了递归调用。此功能现在仅被调用约20次。无需缓存结果,因为它们不会被重用。该函数现在返回一个查询。格式现在位于它所属的视图