2010-03-15 2 views
3

MySQL 및 ColdFusion을 사용하여 검색 결과에 대한 페이지 매김을 만들려고합니다. 제 의도는 단일 페이지에 표시 할 수있는 쿼리 만 검색하므로 프로세스가 효율적입니다. 내 함수에서 두 개의 쿼리를 사용했지만, 나는 다음과 같은 코드 페이지를 매기하지 않는 cfinvoke.MySQL 및 ColdFusion에서 페이징 기능을 만드는 방법

에 두 개의 변수를 반환하지 수 있지만, 그것은 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> 

이 사용을 논리는, 나는 페이지에 표시 할 필요 표시 할 수 있습니다

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

내가 같은 페이지에서 쿼리를 실행 한 경우가 많은 튜토리얼을 따라하기 쉬운 것입니다. 그러나 쿼리는 함수에서 실행 중입니다. 데이터를 표시하는 것은 쉽지만 페이지 매기기는 나에게 악몽이되었습니다. 여기 제 기능입니다 :에 대한 결과가있는 경우

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

가 그럼 난 생각 :

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

이 페이지를 매기려면, 나는 (카운트 문을 사용하여 새 쿼리) 다음에 제 기능을 수정하는 생각 반환, 나는 중첩 된 쿼리를 실행하고 매김 변수를 만들 것입니다 : RESULTCOUNT 및 resultData :

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

가 나는 두 개의 변수를 반환 생각. #pageCount #을 사용하여 페이지 매김을 만들고 # resultData #을 사용하여 출력을 표시합니다. 문제는 동일한 cfinvoke 태그에서 두 개의 변수를 반환 할 수 없다는 것입니다. 올바른 방법에 접근하는 방법에 대한 아이디어가 있습니까? 나는 따라야 할 논리에 관해서는 완전히 잃어버린다.


편집 : 나는 지금 페이지를 매기는 다음 코드를 사용하고 있습니다 (유일한 문제는 #의 CGI.SCRIPT_NAME 번호를 사용하여 그것들을 지 웁니다 때문에 모든 검색은 URL로 다시 필터링 지금은 repass에있을 것입니다) :

결과는 엄청난 수없는 경우
<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> 
+0

새로운 질문이있는 경우, 당신은 새로운 별도의 스레드를 열어야합니다. 3 년 된 스레드의 업데이트보다주의를 끌 가능성이 큽니다. – Leigh

+0

@Leigh not really, 다른 사람들이 도움이 될 수 있도록 몇 가지 표현을 수정했습니다. D - 건배! – Mohamad

+0

@ 모하메드 - 아, 내 나쁜 :) 질문 텍스트 섹션, 즉 "편집 내역"이 아닌 "개정 내역"(http://stackoverflow.com/posts/2451108/revisions) 섹션을보고있었습니다. – Leigh

답변

5

, 당신은 모든 것을 반환 같은 SQL로 유지하고 당신이 그것을 표시 할 때

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

는, 볼 수 있습니다 : http://www.coldfusionjedi.com/index.cfm/2006/4/24/ColdFusion-and-Pagination을. 쿼리 쿼리가 필요하지 않습니다.

이 문제는 내가 같은 cfinvoke 태그에 두 변수를 반환 할 수 있습니다 귀하의 질문을

대답합니다.

왜 동일한 cfinvoke에서 두 개의 변수를 반환 하시겠습니까? DB 수준에서 진정한 페이징을 사용 countResult()와 getResultData (페이지, RecordsPerPage) getResultData (페이지, 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> 

: 대신,이 개 함수를 작성

당신은 DB에서 진정한 pagnation을하고 싶은 경우 수준 인 경우 LIMITOFFSET을 MySQL에 사용하십시오.

totalNumOfPages = ceiling(countResult()/recordsPerPage); 

다른 질문 :

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

가 얼마나 많은 페이지 파악하려면? 두 함수와 두 개의 데이터베이스 통화를, 나는 (그러나하지 MySQL의에서) 전에 다음과 같이 그것을 한 적이보다는

+2

아주 잘 헨리! :-) –

+0

감사합니다, Henry, 정말 도움이됩니다. 유일한 것은 페이지 작성을 위해 변수가 있어야하는 위치에 대해 여전히 혼란 스럽습니다. 목록에 나온 두 번째 방법은 편리한 자습서를 생각해 볼 수 있습니까? 내가 묻는 이유는 괜찮습니다. 두 함수 사이의 관계를 만드는 데 혼란 스럽습니다 ... 또는 한 함수에서 다른 함수 (getResultData의 resultCount)로 변수를 전송하는 방법 ... 죄송합니다. 난처한 코멘트처럼, 너무 빨리 배우기 때문에 계속 지탱할 수 없습니다! – Mohamad

+0

"페이지를 만들 때 변수가 있어야하는 위치"는 무엇을 의미합니까? – Henry

1

는 :

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

그것은 'rowsFound'라는 반환 된 레코드에 열을 추가합니다. 별로 정규화되지는 않지만 큰 문제는 아닙니다. DB 히트를 최소화 할만한 가치가 있을지도 모른다.

나는 그것이 '스칼라 피연산자로 하위 쿼리'라고 생각 : http://dev.mysql.com/doc/refman/5.1/en/scalar-subqueries.html

토니

관련 문제