2013-09-24 1 views
2

오라클 데이터베이스를 사용해 보았습니다. 페이지 매김에서 문제가 발견되었습니다. 지난 번 MySQL에서 사용하는 것이 좋습니다.PHP Oracle Pagination Cant 데이터 표시 ROWNUM 사용

내 코드를 참조하십시오 : 나는 ROWNUM을 사용했습니다

<?php 
$page = $_POST['page']; 
$cur_page = $page; 
$page -= 1; 
$per_page = 3; 
$previous_btn = true; 
$next_btn = true; 
$first_btn = true; 
$last_btn = true; 
$start = $page * $per_page; 

$query_pag_data = "SELECT P.FORM_NO, P.MODEL_NO, P.PRODUCTION_STATUS, P.REMARKS, P.DATE_ADDED, P.TIME, P.QTY_PLAN, M.MODEL_NO, M.MODEL_NAME 
        FROM SEIAPPS_PRODUCTION_STATUS P, SEIAPPS_MODEL M 
        WHERE ROWNUM BETWEEN $start AND $per_page AND P.MODEL_NO = M.MODEL_NO ORDER BY P.DATE_ADDED DESC, P.TIME"; 

$result_pag_data = oci_parse($c1, $query_pag_data); 
oci_execute($result_pag_data); 

을,하지만 난 2 페이지 또는 다음 페이지를 열고 자 할 때, 어떤 데이터를 표시하지 않았다. 반면에 여전히 테이블에 더 많은 데이터가 있습니다.

누구든지 조언을 구하십시오. 감사합니다.

+0

1) OCI는 [ 'oci_bind_by_name' (http://www.php.net/manual/en/function.oci-bind-by-name.php) 그래서주세요 갖는다 제발 SQL 쿼리에 모든 것을 때우는 대신 사용하십시오; 2) 페이지 당 3, 페이지 2에서 SQL은 3 ~ 3 사이의 rownum, 3 페이지가되며 SQL은 'rownum 6 ~ 3'이됩니다. – Passerby

+0

@Passerby의 예는 무엇입니까? –

답변

2

ROWNUM은 MySQL에서 LIMIT과 같지 않습니다. MySQL에서

,

LIMIT 절 는 두 개의 인수와 함께 ... SELECT 문에 의해 반환되는 행의 수를 제한하는 데 사용할 수 있습니다, 첫 번째 인수가 반환하는 첫 번째 행의 오프셋 (offset)를 지정, 두 x 째는 리턴 할 최대 행 수를 지정합니다. 최초 행의 오프셋은 0 (안 1)이다

Oracle에서
SELECT * FROM tbl LIMIT 5,10; # Retrieve rows 6-15 

쿼리에 의해 반환 된 각 행

에서, ROWNUM 의사 열이 순서를 나타내는 번호를 반환하는 Oracle은 테이블 또는 결합 된 행 세트에서 행을 선택합니다. 선택된 첫 번째 행은 ROWNUM이 1이고, 두 번째 행은 2입니다.

앞의 예에서
SELECT * 
    FROM (SELECT * FROM employees ORDER BY employee_id) 
    WHERE ROWNUM < 11; 

ROWNUM 값은 최상위 SELECT 문의하는, 그래서 행이 이미 하위 쿼리 employee_id입니다으로 정렬 된 후 그들은 생성됩니다.

그래서 코드의 문제점은 다음과 같습니다

  • WHERE ROWNUM BETWEEN :startrow AND :perpage

    논리적으로 잘못된, ROWNUM가 아닌 "숫자 행의"표시, 행 인덱스 지표가있다. ROWNUM BETWEEN a AND b은 a에서 b로 순서화 된 행을 반환하는 것을 의미합니다. 행 # 1에서 행 # 3, 행 # 1 및 행 3 개.

    따라서 ROWNUM BETWEEN a AND b이 실제로 작동하더라도 쿼리의 '페이지 2'를 얻으려면 논리적으로 ROWNUM BETWEEN :startrow AND :endrow이 필요합니다. ROWNUM BETWEEN 4 AND 6;

  • ROWNUM BETWEEN :startrow AND :endrowROWNUM이을 설정 선택된의 행 의 순서를 나타내는 의사 열 때문에 실제로, 1보다 큰 시작 행에 대해 작동하지 않을 것입니다

    그래서 당신은 예를 들어, 실행할 때SELECT...WHERE ROWNUM BETWEEN 4 AND 6,

    • 첫 경기는, 오라클은 생각한다 "고 ROWNUM이 될 것인가에 4 ~ 6?" 아직 선택된 행이 없으므로 ROWNUM이 선택됩니다.을 선택하면 오라클이 포기합니다.
    • 두 번째 경기는 "4시 6 분입니까?" 아니요. 행이 선택되어 있지 않으므로 No입니다. 그러면 여전히 1이됩니다.
    • 세 번째 일치, 동일;
    • ...

    는 전혀 결과가 없습니다.

    욕망 출력을 얻으려면, 당신은 다음과 같이 서브 쿼리에서 쿼리를 포장, 외부 행 번호를 확인해야합니다 :

SELECT * FROM 
    (SELECT ROWNUM rn, t.* 
    FROM 
     (SELECT ... 
     FROM ... 
     WHERE ... 
     ORDER BY ...) t 
) 
    WHERE rn>=:startrow AND rn<=:endrow 

은 행 순서가 확인하기 전에 해결되는 것을 보장하기 위해 행의 순서.

  • 그리고 OCI는 prepared statementvariable binding을 지원하는, 코딩 스타일에 대한

    , 당신은 를 사용해야합니다

    바인딩은 명령문의 이전 실행에서 문 컨텍스트와 캐시를 다시 사용하기 위해 데이터베이스를 수 , ... 바인드 변수와 연관된 데이터가 절대로 SQL 문의 일부로 처리되지 않기 때문에 바인딩은 SQL 주입 문제를 줄입니다.

$statement=oci_parse("... WHERE rn>=:start AND rn<=:end"); 
oci_bind_by_name($statement,":start",$start,-1,SQLT_INT); 
oci_bind_by_name($statement,":end",intval($start+$per_page-1),-1,SQLT_INT); 
oci_execute($statement);