2012-05-06 9 views
0

Я пытаюсь постраничной свои продукты с помощью PHP и SQL Server 2008. Я после этого видео-учебник, чтобы помочь мне понять, как работает пагинация:PHP Разбивка с SQL Server 2008

http://www.youtube.com/watch?feature...&v=K8xYGnEOXYc

Единственная проблема заключается в что этот учебник о MySQL и SQL Server 2008

Вот мой код, который я написал до сих пор:

$tsql = "SELECT * 
     FROM products INNER JOIN product_catalogue 
     ON products.catalogueID = product_catalogue.catalogueID 
     WHERE category1 = '1' 
     ORDER BY productID ASC"; 
$stmt = sqlsrv_query($conn,$tsql); 
$nr = sqlsrv_num_rows($stmt); // Get total of Num rows from the database query 
if (isset($_GET['pn'])) { // Get pn from URL vars if it is present 
    $pn = preg_replace('#[^0-9]#i', '', $_GET['pn']); // filter everything but numbers for security(new) 
} else { // If the pn URL variable is not present force it to be value of page number 1 
    $pn = 1; 
} 
//This is where we set how many database items to show on each page 
$itemsPerPage = 10; 
// Get the value of the last page in the pagination result set 
$lastPage = ceil($nr/$itemsPerPage); 
// Be sure URL variable $pn(page number) is no lower than page 1 and no higher than $lastpage 
if ($pn < 1) { // If it is less than 1 
    $pn = 1; // force it to be 1 
} else if ($pn > $lastPage) { // if it is greater than $lastpage 
    $pn = $lastPage; // force it to be $lastpage's value 
} 

// This creates the numbers to click in between the next and back buttons 
// This section is explained well in the video that accompanies this script 
$centerPages = ""; 
$sub1 = $pn - 1; 
$sub2 = $pn - 2; 
$add1 = $pn + 1; 
$add2 = $pn + 2; 
if ($pn == 1) { 
    $centerPages .= '&nbsp; <span class="pagNumActive">' . $pn . '</span> &nbsp;'; 
    $centerPages .= '&nbsp; <a href="' . $_SERVER['PHP_SELF'] . '?pn=' . $add1 . '">' . $add1 . '</a> &nbsp;'; 
} else if ($pn == $lastPage) { 
    $centerPages .= '&nbsp; <a href="' . $_SERVER['PHP_SELF'] . '?pn=' . $sub1 . '">' . $sub1 . '</a> &nbsp;'; 
    $centerPages .= '&nbsp; <span class="pagNumActive">' . $pn . '</span> &nbsp;'; 
} else if ($pn > 2 && $pn < ($lastPage - 1)) { 
    $centerPages .= '&nbsp; <a href="' . $_SERVER['PHP_SELF'] . '?pn=' . $sub2 . '">' . $sub2 . '</a> &nbsp;'; 
    $centerPages .= '&nbsp; <a href="' . $_SERVER['PHP_SELF'] . '?pn=' . $sub1 . '">' . $sub1 . '</a> &nbsp;'; 
    $centerPages .= '&nbsp; <span class="pagNumActive">' . $pn . '</span> &nbsp;'; 
    $centerPages .= '&nbsp; <a href="' . $_SERVER['PHP_SELF'] . '?pn=' . $add1 . '">' . $add1 . '</a> &nbsp;'; 
    $centerPages .= '&nbsp; <a href="' . $_SERVER['PHP_SELF'] . '?pn=' . $add2 . '">' . $add2 . '</a> &nbsp;'; 
} else if ($pn > 1 && $pn < $lastPage) { 
    $centerPages .= '&nbsp; <a href="' . $_SERVER['PHP_SELF'] . '?pn=' . $sub1 . '">' . $sub1 . '</a> &nbsp;'; 
    $centerPages .= '&nbsp; <span class="pagNumActive">' . $pn . '</span> &nbsp;'; 
    $centerPages .= '&nbsp; <a href="' . $_SERVER['PHP_SELF'] . '?pn=' . $add1 . '">' . $add1 . '</a> &nbsp;'; 
} 

// This line sets the "LIMIT" range... the 2 values we place to choose a range of rows from database in our query 
$limit = 'LIMIT ' .($pn - 1) * $itemsPerPage .',' .$itemsPerPage; 

// Now we are going to run the same query as above but this time add $limit onto the end of the SQL syntax 
// $sql2 is what we will use to fuel our while loop statement below 
$tsql2 = "SELECT * 
     FROM products INNER JOIN product_catalogue 
     ON products.catalogueID = product_catalogue.catalogueID 
     WHERE category1 = '1' 
     ORDER BY productID ASC $limit"; 

$stmt2 = sqlsrv_query($conn,$tsql2); 

$paginationDisplay = ""; // Initialize the pagination output variable 
// This code runs only if the last page variable is not equal to 1, if it is only 1 page we require no paginated links to display 
if ($lastPage != "1"){ 
    // This shows the user what page they are on, and the total number of pages 
    $paginationDisplay .= 'Page <strong>' . $pn . '</strong> of ' . $lastPage. '&nbsp; &nbsp; &nbsp; '; 
    // If we are not on page 1 we can place the Back button 
    if ($pn != 1) { 
     $previous = $pn - 1; 
     $paginationDisplay .= '&nbsp; <a href="' . $_SERVER['PHP_SELF'] . '?pn=' . $previous . '"> Back</a> '; 
    } 
    // Lay in the clickable numbers display here between the Back and Next links 
    $paginationDisplay .= '<span class="paginationNumbers">' . $centerPages . '</span>'; 
    // If we are not on the very last page we can place the Next button 
    if ($pn != $lastPage) { 
     $nextPage = $pn + 1; 
     $paginationDisplay .= '&nbsp; <a href="' . $_SERVER['PHP_SELF'] . '?pn=' . $nextPage . '"> Next</a> '; 
    } 
} 

// Build the Output Section Here 
$outputList = ''; 
while($row = sqlsrv_fetch_array($stmt2)){ 
     $id = $row["productID"]; 
     $product_name = $row["product_name"]; 
     $product_price = $row["product_price"]; 
     $outputList .= '<h1>' . $product_name . '</h1><h2>' . $product_price . ' </h2><hr />'; 
} 
?> 

As вы можете увидеть прямо над моим вторым запросом, я установил диапазон LIMIT и попытаюсь вставить переменную $ limit в запрос SELECT. К сожалению, это не работает с SQL Server.

Так что это код, который я не знаю, как преобразовать в SQL Server должным образом:

$limit = 'LIMIT ' .($pn - 1) * $itemsPerPage .',' .$itemsPerPage; 
$tsql2 = "SELECT * 
     FROM products INNER JOIN product_catalogue 
     ON products.catalogueID = product_catalogue.catalogueID 
     WHERE category1 = '1' 
     ORDER BY productID ASC $limit"; 

$stmt2 = sqlsrv_query($conn,$tsql2); 

Я попытался преобразовать его в формат SQL Server должен понять, но, как я новичок в PHP и к программированию в целом, я не смог заставить его работать

$limit = ($pn - 1) * $itemsPerPage; 
$next_page = $itemsPerPage; 
$tsql2 = "SELECT TOP $next_page productID, product_name, product_price 
     FROM products INNER JOIN product_catalogue 
     ON products.catalogueID = product_catalogue.catalogueID 
     WHERE category1 = '1' AND productID NOT IN(SELECT TOP $limit productID FROM products INNER JOIN product_catalogue 
     ON products.catalogueID = product_catalogue.catalogueID 
     WHERE category1 = '1' 
     ORDER BY productID ASC)"; 
$stmt2 = sqlsrv_query($conn,$tsql2); 

ждем вашего ответа

Спасибо

+0

Почему вы хотите преобразовать код SQL? Разве это не работает? Вы получаете сообщение об ошибке? – pomeh

+0

Это не работает, потому что SQL Server 2008 не поддерживает функцию LIMIT. И я знаю, что должна быть дорога вокруг этой проблемы, но у меня просто недостаточно опыта программирования, чтобы заставить ее работать. Я получаю предупреждение «sqlsrv_fetch_array() ожидает, что параметр 1 будет ресурсом, boolean», и я знаю, что это связано с этим значением LIMIT – Alex

+0

Итак, этот пост должен помочь http://stackoverflow.com/questions/9013177/mysql-limit-clause- analog-for-sql-server – pomeh

ответ

2

Вот решение, которое мы используем, как правило, чтобы решить эту проблему:

/** 
* Constructs a offsetted query. 
* 
* Because of the major differences between MySQL (LIMIT) and 
* SQL Server's cursor approach to offsetting queries, this method 
* allows an abstraction of this process at application level. 
* 
* @param int $offset the offset point of the query 
* @param int $limit the limit of the query 
* @param string $select the fields we're selecting 
* @param string $tables the tables we're selecting from 
* @param string $order the order by clause of the query 
* @param string $where the conditions of the query 
* 
* @return string 
*/ 
function offset($offset, $limit, $select, $tables, $order, $where='') 
{ 
    $ret .= 'SELECT [outer].* FROM (
      SELECT ROW_NUMBER() OVER(ORDER BY ' . $order .') as ROW_NUMBER, 
      ' . $select . ' 
      FROM ' . $tables . ($where ? ' WHERE ' . $where : '') 
     .') AS [outer] 
      WHERE [outer].[ROW_NUMBER] BETWEEN ' 
     . (intval($offset)+1).' AND '.intval($offset+$limit) 
     . ' ORDER BY [outer].[ROW_NUMBER]'; 

    return $ret; 
} 
+0

Благодарим вас за ответ. Я никогда не использовал функции php раньше, как я могу применить эту функцию к моему конкретному сценарию? – Alex

0

Хотя я не какой-нибудь хороший опыт в PHP. Но у меня есть возможность разбиения на страницы в MS SQL Server с помощью ASP.Net. Я думаю, будет лучше, если вы создадите хранимую процедуру, которая будет выполнять все pagination-работы в одном SP и получить набор результатов в PHP. Вот СП, который может вам помочь:

USE [your_db] 
GO 
CREATE PROCEDURE [dbo].[usp_product_paginate] 
@page_number INT, @page_size INT 
AS 
BEGIN 
    SELECT ROW_NUMBER() OVER (ORDER BY productID ASC) row_num,productId,productName 
    INTO #temp 
    FROM products INNER JOIN product_catalogue ON products.catalogueID = product_catalogue.catalogueID 
    WHERE category1 = '1'; 

    SELECT productId,productName, 
    @page_size AS page_size,(SELECT Min(row_num) FROM #temp)AS first_row, (SELECT COUNT(*) FROM #temp) AS tot_row 
    FROM #temp 
    WHERE row_num > (@page_number - 1) * @page_size and row_num <= @page_number * @page_size; 
END