Domanda

Sto cercando di creare l'impaginazione per i risultati di ricerca utilizzando MySQL e ColdFusion. La mia intenzione è quella di recuperare solo le query che possono essere visualizzati in una singola pagina, rendendo così il processo efficiente. Ho provato ad utilizzare due query nella mia funzione, ma non potevo tornare due variabili al cfinvoke.

Il seguente codice non compagine, ma visualizza i risultati di ricerca risultato utilizzando un CFC:

<!---DEFINE DEFAULT STATE--->
<cfparam name="variables.searchResponse" default="">
<cfparam name="URL.titleName" default="">
<cfparam name="URL.genreID" default="">
<cfparam name="URL.platformID" default="">

<!---TitleName can only be blank if one or both genre and platform are selected--->
<cfif StructKeyExists(URL, "searchQuery") AND (Len(Trim(URL.titleName)) LTE 2 AND Len(URL.genreID) IS 0 AND Len(URL.platformID) IS 0)>
    <cfset variables.searchResponse = "invalidString">
<cfelseif StructKeyExists(URL, "searchQuery")>
    <cfinvoke component="gz.cfcomp.test" method="searchGames" returnvariable="resultData" argumentcollection="#URL#">
    <cfset variables.searchResponse = "hasResult">
</cfif>

<cfif searchResponse EQ "hasResult" AND resultData.RecordCount EQ 0>
    <cfset variables.searchResponse = "noResult">
</cfif>

Con questa logica, posso visualizzare ciò che ho bisogno di visualizzare sulla pagina:

<cfif searchResponse EQ "invalidString">
     <cfoutput>Invalid search</cfoutput>
</cfif>
<cfif searchResponse EQ "noResult">
     <cfoutput>No results found</cfoutput>
</cfif>
<cfif searchResponse EQ "hasResult">
     <cfoutput>Display Results</cfoutput>
</cfif>

Se io fossi l'esecuzione della query sulla stessa pagina, sarebbe facile da seguire i molti tutorial là fuori. Ma le query sono in esecuzione in una funzione. Visualizzazione dei dati è facile, ma l'impaginazione è diventato un incubo per me. Qui è la mia funzione:

<cffunction name="searchGames" access="public" output="false">
    <cfargument name="titleName" required="no" type="string">
    <cfargument name="genreID" required="no" type="string">
    <cfargument name="platformID" required="no" type="string">    

    <!--- DEFINE LOCAL VARIABLES--->
    <cfset var resultData = "">        
    <!---GET DATA--->
    <cfquery name="resultData" datasource="myDSN">
        SELECT *
            <!---JOINS FOR GENRE/PLATFORM GO HERE--->
        WHERE
            <!---CONDITIONS GO HERE--->
    </cfquery>
    <!---RETURN VARIABLE--->
    <cfreturn resultData>
</cffunction>   

Per impaginare, ho pensato a modificare la mia funzione al seguente (una nuova query utilizzando un'istruzione conteggio):

<!--- DEFINE LOCAL VARIABLES--->
<cfset var resultCount = "">        
<!---GET DATA--->
<cfquery name="resultCount" datasource="myDSN">
    SELECT COUNT(gameID) AS rowsFound FROM GAMES
        <!---JOINS FOR GENRE/PLATFORM GO HERE--->
    WHERE
        <!---CONDITIONS GO HERE--->
</cfquery>
<!---RETURN VARIABLE--->
<cfreturn resultCount>

Poi ho pensato che se c'è un risultato di tornare, vorrei eseguire una query nidificate e creare le variabili di impaginazione:

<cfif resultCount.rowsFound GTE 0>
<cfparam name="pageNumber" default="1">
<cfset var recordsPerPage = 5>
<cfset var numberOfPages = Int(resultCount.RecordCount / recordsPerPage)>
<cfset var recordsToSkip = pageNumber * recordsPerPage - recordsPerPage>

<!---DEFINE LOCAL VARIABLE--->
<cfset var resultData = "">

<cfquery name="resultData" datasource="myDSN">
<!---GET DATA AND SEND IT BACK USING LIMIT WITH #recordsToSkip# and #RecordsPerPage#--->
</cfquery>
<!---RETURN VARIABLE--->
<cfreturn resultData>
</cffunction>

Ho pensato che sarei tornato due variabili: resultCount e resultData. Vorrei usare # resultCount # per costruire la mia impaginazione, e # # resultData per visualizzare l'output. Il problema è che non posso restituire due variabili nello stesso tag cfinvoke. Tutte le idee di come affrontare il modo giusto? Sono totalmente perso, come la logica che ho bisogno di seguire.


EDIT: Sto utilizzando il seguente codice per impaginare ora (l'unico problema è ora devo ripassare tutta la ricerca filtra nuovamente dentro l'URL perché usando # # CGI.SCRIPT_NAME li cancella):

<cfif searchResponse EQ "hasResult">
<!---BASICALLY, IF resultCount.rowsFound is not 0, execute this method--->
     <cfinvoke component="gz.cfcomp.test" method="getResult" returnvariable="resultData" argumentcollection="#URL#">

     <cfif URL.currentPage IS 1>
          --
     <cfelse>
          <a href="#CGI.SCRIPT_NAME#?searchQuery=&titleName=#URL.titleName#&genreID=#URL.genreID#&platformID=#URL.platformID#&currentPage=#currentPage-1#">Prev Page</a>
     </cfif>

     <cfif URL.currentPage * recordsPerPage LT resultCount.rowsFound>
          <a href="#CGI.SCRIPT_NAME#?searchQuery=&titleName=#URL.titleName#&genreID=#URL.genreID#&platformID=#URL.platformID#&currentPage=#currentPage+1#">Next Page</a>
     <cfelse>
          --
     </cfif>

</cfif>
È stato utile?

Soluzione

Se i risultati non è enorme, si può stare con lo stesso SQL che restituisce tutto e utilizzare

<cfoutput query="data" startrow="#url.start#" maxrows="#recordsPerPage#">

quando si visualizza, vedi: http: //www.coldfusionjedi.com/index.cfm/2006/4/24/ColdFusion-and-Pagination . Non è necessaria alcuna query di Query.

Per rispondere alla tua domanda

  

Il problema è che non posso tornare a due   variabili nella stessa tag cfinvoke.

Perché vuoi tornare due variabili nella stessa cfinvoke? Invece, scrivere 2 funzioni: countResult () e getResultData (pagina RecordsPerPage)

<cffunction name="countResult" output="false" returntype="numeric">
  <cfset var resultCount = "">    
  <cfquery name="resultCount" datasource="myDSN">
    SELECT COUNT(gameID) AS rowsFound FROM GAMES
        <!---JOINS FOR GENRE/PLATFORM GO HERE--->
    WHERE
        <!---CONDITIONS GO HERE--->
  </cfquery>
  <cfreturn resultCount.rowsFound>
</cffunction>

Per getResultData (pagina RecordsPerPage) utilizzando vero paging del livello di DB:

Se si vuole fare vero pagnation a livello DB, utilizzare LIMIT e OFFSET in MySQL.

<cffunction name="getResultData" output="false" returntype="Query">
  <cfargument name="page" type="numeric" default="1">
  <cfargument name="recordsPerPage" type="numeric" default="5">

  <cfset var resultData = "">
  <cfset var offset = (page-1) * RecordsPerPage>

  <cfquery name="resultData" datasource="myDSN">
    SELECT * LIMIT #recordsPerPage# OFFSET #offset#
        <!---JOINS FOR GENRE/PLATFORM GO HERE--->
    WHERE
        <!---CONDITIONS GO HERE--->
  </cfquery>

  <cfreturn resultData>
</cffunction>

Per capire quante pagine ci sono:

totalNumOfPages = ceiling(countResult() / recordsPerPage);

Qualsiasi altra domanda?

Altri suggerimenti

Piuttosto che avere due funzioni e due chiamate al database, ho fatto come questo prima (non in MySQL comunque):

<cffunction name="getResultData" output="false" returntype="Query">
  <cfargument name="page" type="numeric" default="1">
  <cfargument name="recordsPerPage" type="numeric" default="5">

  <cfset var resultData = "">
  <cfset var offset = (page-1) * RecordsPerPage>

  <cfquery name="resultData" datasource="myDSN">
    SELECT *,
      (
        SELECT COUNT(gameID) AS rowsFound
        FROM
          <!---JOINS FOR GENRE/PLATFORM GO HERE--->
        WHERE
          <!---CONDITIONS GO HERE--->
      ) AS rowsFound
      LIMIT #recordsPerPage# OFFSET #offset#
        <!---JOINS FOR GENRE/PLATFORM GO HERE--->
    WHERE
        <!---CONDITIONS GO HERE--->
  </cfquery>

  <cfreturn resultData>
</cffunction>

Si aggiunge una colonna alla recordset restituito chiamato 'rowsFound'. Non molto normalizzata, ma non è un grosso problema. Potrebbe essere la pena di minimizzare i colpi DB.

Credo che sia indicato come 'subquery come operando scalare': http://dev.mysql.com/doc/refman/ 5.1 / it / scalare-subqueries.html

Tony

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top