returning multiple stored procedure result sets from a cfc

血红的双手。 提交于 2019-12-07 15:31:02

问题


I am trying to convert some pages from my app to use cfc's, and one page uses a stored procedure to retrieve a couple sets of data.

Now when I access the results, they act just like a if I used a <cfquery> tag, and all of the functionality that gives. So now I am trying to use this same stored procedure in a cfc that I am building, and I would like to be able access the results in the same manner, and there in lies my problem. I'm not sure how to return multiple queries from the function, without creating an array, which I have started. By the way, the function is incomplete. I was just trying to get something to work. In the below setup I get an array of query objects, but I feel there is a better way to do it.

Here is the <cffuntion>:

<cffunction name="getProfileData" 
            access="public" 
            output="false" 
            returntype="string">

    <cfargument name="cusip" type="string" required="true">
    <cfargument name="report_date" type="date" required="true">
    <cfset var errorMessage = "everything is good">

    <cftry>
        <cfstoredproc datasource="#dsn#" procedure="prc_asset_profile_retrieve">
            <cfprocparam type="in" cfsqltype="cf_sql_varchar" value="#cusip#" dbvarname="@cusip">
            <cfprocparam type="in" cfsqltype="cf_sql_varchar" value="#report_date#" dbvarname="@reportDate">
            <cfprocresult name="profile_head" resultset="1">
            <cfprocresult name="attribution" resultset="2">
            <cfprocresult name="characteristics" resultset="3">
            <cfprocresult name="exposure" resultset="4">
            <cfprocresult name="weights" resultset="5">
            <cfprocresult name="holdings" resultset="6">
        </cfstoredproc>

        <cfset var profileArray = []>
        <cfset #ArrayAppend(profileArray,profile_head)#>

        <cfcatch type="any">
            <cfset errorMessage = "something happened">
        </cfcatch>          
    </cftry>

    <cfreturn profileArray>
</cffunction>

When I output some test data, it matches up

<cfset count = fund_profile.getProfileData("#cusip#","#report_date#")> 
<cfdump var="#count[1]#">
<cfoutput>
    From cfc (##count[1].recordCount##): #count[1].recordCount#<br>
    From stored proc (##profile_head.recordCount##): #profile_head.recordCount#
</cfoutput>

I get:

From cfc (#count[1].recordCount#): 1
From stored proc (#profile_head.recordCount#): 1

But the second way looks so much cleaner.

   -----------------------------WORKING SOLUTION------------------------------ 

So after working with the answer from @leigh, I came up with this.

Here is the full cfc:

<cfcomponent displayname="Fund Profile" hint="This is the cfc that will do the processing of all fund profile information" output="false">
     <cfproperty name = "result1"> <!--- PROFILE HEAD --->
     <cfproperty name = "result2"> <!--- ATTRIBUTION --->
     <cfproperty name = "result3"> <!--- CHARACTERISTICS --->
     <cfproperty name = "result4"> <!--- EXPOSURE --->
     <cfproperty name = "result5"> <!--- WEIGHTS --->
     <cfproperty name = "result6"> <!--- HOLDINGS --->

     <cffunction name="init" 
            displayname="init" 
            hint="This will initialize the object" 
            access="public" 
            output="false" 
            returnType="Any">

        <cfargument name="dsn"  type="string" required="true" />
        <cfargument name="cusip" type="string" required="true" />
        <cfargument name="report_date" type="date" required="true" />

        <cfset variables.dsn = #arguments.dsn#>
        <cfset variables.cusip = #arguments.cusip#>
        <cfset variables.report_date = #arguments.report_date#>

        <cfscript>
            getProfiledata(cusip,report_date);
        </cfscript>     

        <cfreturn this>
    </cffunction>

    <cffunction name="getProfileData" 
            access="private" 
            output="false" 
            returntype="void">

        <cfargument name="cusip" type="string" required="true">
        <cfargument name="report_date" type="date" required="true">

        <cfstoredproc datasource="#dsn#" procedure="prc_asset_profile_retrieve">
             <!--- STORED PROCEDURE HASN'T CHANGED.  SEE ABOVE FOR CODE --->
        </cfstoredproc>

        <cfscript>
            setProfilehead(profile_head);
            setAttribution(attribution);
            setCharacteristics(characteristics);
            setExposure(exposure);
            setWeights(weights);
            setHoldings(holdings);
        </cfscript>

        <cfreturn>
    </cffunction>

    <!--- NOT GOING TO INCLUDE ALL SETTERS AND GETTERS, --->
    <!--- BECAUSE THEY ARE ALL THE SAME OTHER THAN THE NAMES --->

    <cffunction name="setProfileHead" access="private">
        <cfargument name="ProfileHead">
        <cfset variables.result1 = arguments.ProfileHead>       
    </cffunction>

    <cffunction name="getProfileHead" access="public" returntype="query">
        <cfreturn variables.result1>
    </cffunction>

</cfcomponent>

Here is the code from the calling page:

<cfset fund_profile = CreateObject("component", "CFCs.fund_profile").init("#dsn#","#cusip#","#report_date#")>
<cfset profile_head = fund_profile.getProfileHead()>

Sorry for all the code, but I wanted to make the code available. So does anyone see any problems with what I came up with?


回答1:


I would create other methods in the CFC that would each be responsible for returning a result from the stored proc. In the main method , call setters setProfileHead(profilehead:profileHead)

<cffunction name=ProfileHead>
    <cfarguments name=ProfileHead />
    <cfset variables.profilehead = arguments.profilehead>
 </cffunction>

Then...

<cffunction name=GetProfileHead>
    <cfreturn variables.profileHead />
</cffuction>



回答2:


A function can only return a single value. If you wish to return multiple values, you will need to use some type of complex object (an array, structure, ...) If arrays are not intuitive enough, you could place the queries in a structure and return that instead. Then the calling page could access the queries by name, rather than index.

(Side note, be sure to properly var scope/localize all function variables.)

 <cfset var data = {}>
 ...
 <!--- store query results in structure --->
 <cfset data.profile_head = profile_head>
 <cfset data.attribution = attribution>
 ... 
 <cfset data.holdings = holdings>
 <!--- return structure --->
 <cfreturn data>


来源:https://stackoverflow.com/questions/9982918/returning-multiple-stored-procedure-result-sets-from-a-cfc

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!