Returning multiple result sets of stored procedures from cfc

I am trying to convert some pages from my application to use cfc and one page is using a stored procedure to retrieve multiple datasets.

Now when I access the results, they act the same as if I were using the tag <cfquery>

and all the functions that give. So now I am trying to use this same stored procedure in a cfc that I am creating and I would like to be able to access the results in the same way and that is where my problem lies. I am not sure how to return multiple requests from this function without creating the array I started. By the way, the function is incomplete. I was just trying to get it to work. In the setup below, I am getting an array of request objects, but I believe there is a better way to do it.

Here is <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

<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 procedure proc (# profile_head.recordCount #): 1

But the second method looks much cleaner.

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

      

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

Here is the complete 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 want to make the code available. So does anyone see any problems with what I came up with?

+3


source to share


2 answers


I would create other methods in CFC that would be responsible for returning the result from the stored procedure. In the main setup method calls setProfileHead (profilehead: profileHead)

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

      



Then...

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

      

+3


source


A function can only return one value. If you want to return multiple values, you will need to use some kind of complex object (array, structure, ...). If arrays aren't intuitive enough, you can put queries into a structure and return them. The calling page can then refer to requests by name rather than by index.

(Note that var scope / localize all function variables must be correct.)



 <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>

      

+8


source







All Articles