2017-06-28 2 views
2

Ich baue eine Webseite, die bei der Webformular-Übermittlung einen AJAX-Anruf tätigt. AJAX ruft dann eine cfc auf, in der eine Funktion eine gespeicherte SQL-Prozedur aufruft, die die Webformularwerte als Eingabeargumente übergibt. Bis hier ist in Ordnung, aber ich bin verwirrt darüber, wie Daten zurück an die aufrufende AJAX-Funktion zurückgegeben werden, wenn mehrere Ergebnismengen von der gespeicherten Prozedur zurückgegeben werden.Mehrere cfquery-Ergebnisse zurück an AJAX-Aufruf zurückgeben

Um es klarer zu machen, hat die gespeicherte Prozedur intern viele SELECT-Transaktionen und jeder von diesen wird als Teil von cfprocresult im cfstoredproc erfasst. Wenn es nur ein cfprocresult war, scheint es einfach, es an AJAX zurückzugeben, aber wie sende ich mehrere cfprocresult-Ergebnisse zurück an die aufrufende AJAX-Funktion?

Pseudo-Code unten:

AJAX: ---------

$.ajax(

     { 

      type: “post”, 

      url: "Contacts.cfc", 

      data: { 

       method: "retrieveCustomers", 

       username: this.DOMReferences.Name.val(), 



       }, 

      dataType: "json", 





      success: function(objResponse){ 



       if (objResponse.SUCCESS){ 



// rest of AJAX to process returned data here 

Contacts.cfc ---------

<cfcomponent> 
<cffunction name="retrieveCustomers" returntype="query"> 

<cfstoredproc datasource="#application.dsn_spoon#" procedure="proc_getUsers_paged"> 
      <cfprocparam cfsqltype="cf_sql_varchar" value="#username#"> 
      <cfprocresult name="qResult1" resultset="1"> 
      <cfprocresult name="qResult2" resultset="2"> 
      <cfprocresult name="qResult3" resultset="3"> 
</cfstoredproc> 


// how do i return all 3 result sets back to calling AJAX function? 

</cffunction> 
</cfcomponent> 

HINWEIS: Ich habe sehr wenig Kontrolle, um die Logik der gespeicherten Prozedur zu ändern. Die vorhandene Webseite verwendete beim Aufrufen der cfstoredproc-Komponente eine Aktualisierung der Seite selbst und verwendete AJAX nicht. Ich schreibe die Benutzeroberfläche neu, um stattdessen AJAX zu verwenden.

Danke!

+1

Ich denke, was Sie tun können, ist eine Struktur erstellen und speichern Sie die Ergebnismengen darin. Verwenden Sie anschließend die SerializeJSON-Funktion, um die Struktur in JSON zu konvertieren, und geben Sie sie als Antwort an Ajax zurück. Sobald Sie die Ajax-Antwort erhalten haben, müssen Sie nur noch analysieren und manipulieren. –

+1

Auch wenn Sie Ihre CFC-Funktion direkt mit Ajax aufrufen, müssen Sie access = remote setzen und returntype = JSON setzen –

+1

@Keshavjha - Danke. Ich denke, ich verstehe den Ansatz jetzt. Werde es irgendwann ausprobieren! – maverick

Antwort

1

Man könnte so etwas wie dies versuchen:

<cfcomponent> 
<cffunction name="retrieveCustomers" returntype="struct" returnformat="json" access="remote"> 

<cfstoredproc datasource="#application.dsn_spoon#" procedure="proc_getUsers_paged"> 
     <cfprocparam cfsqltype="cf_sql_varchar" value="#username#"> 
     <cfprocresult name="qResult1" resultset="1"> 
     <cfprocresult name="qResult2" resultset="2"> 
     <cfprocresult name="qResult3" resultset="3"> 
</cfstoredproc> 

<cfset _results = structNew()> 
<cfset _results.result1 = qResult1> 
<cfset _results.result2 = qResult2> 
<cfset _results.result3 = qResult3> 

<cfreturn _results> 


</cffunction> 
</cfcomponent> 

Die hier Nachteil ist, dass Sie die qResults Massage benötigen, um. Normalerweise würde ich jede Abfrage durchlaufen und ein Array erstellen. Aber das ist nur persönliche Vorliebe. Was ich normalerweise mache, wenn ich eine Abfrage zurücksende, ist Schleife darüber und baue eine neue Struktur. Dies liegt daran, dass ich möglicherweise zusätzliche Aktionen für jede Eigenschaft ausführen möchte.

... 
<cfset _results = structNew()> 
<cfset _results.result1 = arrayNew()> 
<cfset _results.result2 = arrayNew()> 
<cfset _results.result3 = arrayNew()> 

<cfloop query="qResult1"> 
    <cfset _result = structNew()> 
    <cfset _result.col1 = qResult1.col1> 
    <cfset _result.col2 = qResult1.col2> 
    <cfset _result.col3 = qResult1.col3> 
    <cfset arrayAppend(_results.result1,_result)> 
</cfloop> 

<cfloop query="qResult2"> 
    <cfset _result = structNew()> 
    <cfset _result.cola = qResult2.cola> 
    <cfset _result.colb = qResult2.colb> 
    <cfset _result.colc = qResult2.colc> 
    <cfset _result.cold = qResult3.cold> 
    <cfset arrayAppend(_results.result2,_result)> 
</cfloop> 

<cfloop query="qResult3"> 
.... 
</cfloop> 

<cfreturn _results> 

Für mich ist dies sauberer und einfacher zu arbeiten. Es kann mehr Overhead- und Server-seitige Verarbeitung erfordern, aber es ist einfacher zu warten. Und es gibt kein Parsing auf der JS-Seite, da die zurückgegebene Struktur in der richtigen JSON-Formatierung ist.

+1

Danke! Ziemlich neu für die Verwendung von Strukturen, so zwei Follow-up-Fragen - a. qResult1, qResult2, ... - diese können unterschiedliche Spaltenzahlen haben, oder? Wie in, qResult1 Ausgabe von Tabelle1 und qResult2 Ausgabe von Tabelle2 wobei Tabelle1 und Tabelle2 völlig unterschiedliche Tabellen sind, würde dies keine Probleme verursachen, wenn ich es eine Struktur machen - richtig? b. Könnten Sie bitte weitere Details zum "caveat" -Teil hinzufügen? Ich habe nicht recht verstanden, warum ich die qResults massieren müsste. Ich denke daran, die Daten zurück an AJAX zu geben und sie dort zu analysieren. danke nochmal! – maverick

+1

Denken Sie an eine Struktur als Container für andere Variablen.Es spielt keine Rolle, welche Art von Variablen (einfach, Array, Abfrage, andere Struktur, etc.) sie sind. Der Container akzeptiert alles. –

+1

Ja, qResult1, qResult2 ... können verschiedene Spalten haben. Stellen Sie sich eine Struktur als ein Objekt vor. Strukturen haben Eigenschaften, die ein Wert, eine andere Struktur oder ein Array sein können. Durch das Massieren hätte ich "... auf der Javascript-Seite" hinzugefügt. Es ist eine Weile her, seit ich ein Abfrageobjekt direkt zurück zu Javascript zurückgegeben habe. Ich werde meine Antwort mit dem, was ich normalerweise tue, ergänzen. – snackboy

Verwandte Themen