webForumDet fria alternativet

Paging och MSSQL

PHPur PHP

11 svar · 465 visningar · startad av addeweb

addewebMedlem sedan jan. 2004216 inlägg
#1

Jag håller på att göra iordning ett forum. Till det ska jag också ha paging. Eftersom jag använder MSSQL går det inte att använda LIMIT som fungerar hos MySQL, istället får det bli TOP i select-frågan. I LIMIT-frågan finns två värden, startvärde och maxvärde men däremot bara ett värde hos TOP, troligen maxvärdet.

Sidlänkarna fungerar om man ser i status-raden att värdet ändras men raderna i listan ändras inte. Eftersom man ska kunna se raderna 10-20 när man klickat på sidlänken 2:an i << < 1 [2] 3 4 5 > >>, hur gör jag då med startvärdet??

Jag har också kollat hos SQL-forumet men inte fått något vettigt svar. Har sett exempel på en subselect-fråga men jag blev inte klokare av den.

<?php
echo "<h3>Forum</h3>";

$limit = 10; // Antal per sida
$result = mssql_query("SELECT count(*) AS count FROM forum") 
or die("Fungerar ej att räkna antal poster i databasen!");

$row = mssql_fetch_array($result);
$numrows = $row['count'];  // Antal poster i databasen

// Kolla om startvariabel är satt
if(isset($_GET['start']) || $_GET['start'] == ""){
	$start = 0;
}else{
	$start = $_GET['start'];
}

// Räkna ut hur många sidor det blev
$pages = intval($numrows/$limit);
if ($numrows%$limit)
  $pages++;
 
// Hämta länk till förstasidan och föregående sida
if ($start > 0) {
  $numlink = '<b><a href="?start=0">««</a></b> ';
  $numlink .= '<b><a href="?start='.($start - $limit).'">«</a></b> ';
} else {
  $numlink = '<b>««</b> ';
  $numlink .= '<b>«</b> ';
}
 
// Hämta sidonummer
for ($i = 1; $i <= $pages; $i++) {
  $newoffset = $limit*($i-1);
  if ($start == $newoffset)
    $numlink .= ' <b>[</b>'.$i.'<b>]</b> ';
  else
    $numlink .= '<a href="?start='.$newoffset.'">'.$i.'</a> ';
}
 
// Hämta länk till nästa sida
if ($numrows > ($start + $limit))
  $numlink .= '<b><a href="?start='.($start + $limit).'">»</a></b> ';
else
  $numlink .= '<b>»</b> ';
 
// Hämta sista sidan
if ($start != $newoffset)
  $numlink .= '<b><a href="?start='.$newoffset.'">»»</a></b> ';
else
  $numlink .= '<b>»»</b>';
 
// Hämta data från databasen och skriva ut den

$query = "SELECT TOP $limit * FROM forum where ref_id = 0 ORDER BY datum DESC";

 $result = mssql_query($query, $connection) or die("Det fungerar ej att hämta posterna!"); 

if( rows_affected() == 0 ){

	echo "<table align=\"center\" border=\"0\">\n";
	echo "<tr>\n";
	echo "<td><p><b>Det finns inga inlägg i forumet ännu.</b></td>\n";

	} else {
?>
	<table width="<?=$tbwidth?>" align="center" border="0" cellspacing="0" cellpadding="2">
	<tr>
	<!-- Rubriker -->
	<td bgcolor="<?=$tbtopbgcolor?>" width="40%">
	<b>Rubrik</b>
	</td>
	<td bgcolor="<?=$tbtopbgcolor?>" width="40%">
	<b>Skrivet av</b>
	</td>
	<td bgcolor="<?=$tbtopbgcolor?>" width="40%">
	<b>Senaste</b>
	</td>
	<td bgcolor="<?=$tbtopbgcolor?>" width="40%">
	<b>Svar</b>
	</td>
	</tr>
	<?php
		// Ladda in rader
		while($f=mssql_fetch_array($result))
		{
			$namn = $f["namn"];
			$epost = $f["epost"];
			$amne = $f["amne"];
			$text = $f["text"];
			$id = $f["id"];
			$ref_id = $f["ref_id"];
			$datum = $f["datum"];

			$raknasvar = mssql_num_rows( mssql_query("SELECT * FROM forum where ref_id = $id"));

			$dat = date('j/n H:i', strtotime($datum));

			// Varannan färg
			echo "<tr bgcolor='";
			if( $i++ % 2 == 0 ){
				echo $bg1;
			}else{
				echo $bg2;
			}
			echo "' valign=\"top\">\n";
			echo "<td><a href=\"svar.php?id=$id\"><u>$amne</u></a></td>\n";
			echo "<td>$namn</td>\n";
			echo "<td>$dat</td>\n";
			echo "<td align=\"center\">$raknasvar</td>\n";
			echo "</tr>\n";
			}
		
		// --- Sidnummer under listan. ---
		echo "<tr><td colspan=\"4\" align=\"center\">";
		echo "<br />";
		echo $numlink;
		echo "</td></tr>";
	}
	mssql_close();
?>
addewebMedlem sedan jan. 2004216 inlägg
#2

Tror att jag har ställt den här frågan i fel forum så jag försöker
i SQL-forumet. Hur ska jag få till det med startvärdet?

Återkommer om jag får problem med resten av koden.

addewebMedlem sedan jan. 2004216 inlägg
#3

Har redigerat första inlägget i den här tråden, dvs jag har bytt ut paging-koden mot en bättre.

addewebMedlem sedan jan. 2004216 inlägg
#4

Jag vet inte hur jag ska lösa paging-problemet. Har kollat upp svar om paging i forumet men de är inte mycket till hjälp.

renholmMedlem sedan apr. 20012 266 inlägg
#5

Skrev följande SP för ett tag sedan, vet dock inte hur du använder den i PHP men det löser du säkert :)

CREATE PROCEDURE dbo.sp_entry_Paging
	(@page int,
	@pagesize int)
AS
SET NOCOUNT ON

SELECT IDENTITY(int, 1,1) AS Nr, CONVERT(int, entry_id) AS [ID] INTO #temp FROM Entry

SELECT [ID] FROM #temp WHERE Nr BETWEEN (@page-1)*@pagesize+1 AND @page*@pagesize
DROP TABLE #temp

SET NOCOUNT OFF

SELECT CAST(CEILING(count(*)/CAST (@pagesize AS float)) AS int) FROM Entry -- Totalt antalsidor
addewebMedlem sedan jan. 2004216 inlägg
#6

Tror inte det är klokt att lägga in en sådan kod i själva php-sidan. Såvitt jag vet, ska man gå in i själva databasen och skapa en ny procedur där.

renholmMedlem sedan apr. 20012 266 inlägg
#7

SP skapar du i SQL Servern och anropar sedan den från PHP scriptet.

addewebMedlem sedan jan. 2004216 inlägg
#8

Antar att man inte bara kan ta den rakt av utan några modifieringar och lägga in den i SQL-servern? I procedure-koden skapas en temporär tabell. Hur anropar man den från php-scriptet??

Tabellen för forumet heter forum. Raderna som hämtas till listan sorteras efter datumordning och om ref_id har värdet 0, listas startinlägg på forumets första sida.

renholmMedlem sedan apr. 20012 266 inlägg
#9

Hur man gör i PHP har jag ingen aning om (håller till i ASP.NET samt .NET forumen :) ). Den temporära tabell som skapas ska inte anropas från scriptet i alla fall, det borde räcka med att anropa SP och den svarar då med data från #temp.

Ett problem med ovanstående kod är att det inte riktigt funkar att använda DESC sortering, tyvärr.. har inte kikat på det ännu då jag själv inte behövt det.

addewebMedlem sedan jan. 2004216 inlägg
#10

Ok, men jag låter frågan gå vidare. Vet inte om det är nödvändigt med SP i det här fallet. Ska kolla upp det.

Har studerat ASP.net på nån kurs men är fortfarande inte riktigt bra på det än eftersom jag inte har lärt mig vanlig ASP förut men räknar med att jobba med .NET-språket i framtiden. Snart måste jag använda ASP-språket eftersom jag har hand om en hemsida åt ett företag och som ligger på ett webbhotell som bara stödjer ASP. Planerar använda databaser för hemsidan.

addewebMedlem sedan jan. 2004216 inlägg
#11

Jag testar nu två olika paging-system. Den paging-funktion som
lagts in i tidigare inlägg fungerar inte. Det händer inget när man
klickar på sidlänkarna under listan. Däremot med den andra
paging-funktionen nedan längre ner fungerar det någorlunda.
Det är bara att den första sidan med 10 rader och den andra
sidan (ytterligare 5 rader) är ok men när man klickar på nästa
sida (3) får man likadana två sista rader som föregående sida.
Klickar man på nästa sidlänk (4), ser man på den sidan bara en
rad, likadan som den sista raden på sidan 2 och 3. Egentligen
borde inte sidan 3 och 4 finnas ännu eftersom sidan 2 är inte full
ännu. Jag har skrivit TOP-frågan så här:

$query = "SELECT TOP $row_max * FROM forum WHERE id NOT IN (SELECT TOP $row_start id FROM forum ORDER BY datum DESC) AND ref_id = 0 
ORDER BY datum DESC";

Vad är det som är fel????

<?php 
echo "<h3>Forum</h3>";

$row_max = 10; // Definierar hur många rader per sida. 

if(isset($_GET['p'])) { // Kollar om någon sökt sidan 

	// skapa variabel row_start som innehåller vart posterna skall börja nånstans i tabellen. 
	$row_start = $_GET['p'] * $row_max - $row_max;
	
	// skapa ytterligare en variabel som håller reda på en annan sak. 
	$row_stop = $row_start + $row_max;
	
	// Skapar variabeln innehållande sidnr. 
	$p = $_GET['p'];
	// Om ingen sökt sidan, ja då körs följande kod 
	}else{
	
	// Skapar en annan row_start och row_stop och en $p som 
	// anger att personen inte har varit på sidan innan. 
	$row_start = 0;
	$row_stop = $row_max;
	$p = 1;
	}
	// Antal poster räknas
	$query = "SELECT count(*) AS rows FROM forum";
	$result = mssql_query($query, $connection);

	// Antal svar.
	$row = mssql_result($result, 0, "rows");

	// Räkna ut hur många sidor som behövs  
	$pages = floor($row / $row_max + 1);

	// Kolla så att det inte blir för många sidor.
	if(floor($row / $row_max + 1) == $row / $row_max + 1){
	$pages--;
	}

	$temp = ""; // Sätt variabeln $temp till "" 

	// Räkna ut vilken sida man är på, och använd den som $temp. 
	foreach($_GET as $a => $b){
	if($a !== "p"){
	  $temp = $temp.$a."=".$b."&";
		}
	}

	// Sätter variabeln $pagelinks till sidlänkarna 
	// som man förflyttar sig fram och tillbaka på sidorna med. 
	$pagelinks = "<b>Sidor: </b>";

	// Förflytta sig bakåt
	// if($p > 1){
	// $pagelinks = "<a href=\"index.php?".$temp."p=".$p + 1."\">«</a> ";
	// }

	$i = 0;
	while ($i < $pages){
	$i++;
	if($p == $i){

	// Skapa variabeln som innehåller sidbytena 
	// Vi anropar variabeln $temp som innehåller den aktuella sidan. 
	$pagelinks = $pagelinks."[<b>".$i."</b>]";
	} else {
	$pagelinks = $pagelinks." <a href=\"index.php?".$temp."p=".$i."\">$i</a> ";
		}
	}

	// Förflytta sig framåt
	// if($p < $sidor){
	// $pagelinks = $pagelinks."<a href=\"index.php?".$temp."p=".$p + 1."\">»</a>";
	// }

// Med MySQL
// $query = "SELECT * FROM fORUM WHERE ref_id = 0 ORDER BY datum LIMIT $start, $limit";

// Med MSSQL
$query = "SELECT TOP $row_max * FROM forum WHERE id NOT IN (SELECT TOP $row_start id FROM forum ORDER BY datum DESC) AND ref_id = 0 
ORDER BY datum DESC";

//$query = "SELECT TOP $row_max * FROM forum where ref_id = 0 ORDER BY datum DESC";

 	$result = mssql_query($query, $connection); // Ska ligga kvar

	if( rows_affected() == 0 ){

	echo "<table align=\"center\" border=\"0\">\n";
	echo "<tr>\n";
	echo "<td><p><b>Det finns inga inlägg i forumet ännu.</b></td>\n";

	} else {
?>
	<table width="<?=$tbwidth?>" align="center" border="0" cellspacing="0" cellpadding="2">
	<tr>
	<!-- Rubriker -->
	<td bgcolor="<?=$tbtopbgcolor?>" width="40%">
	<b>Rubrik</b>
	</td>
	<td bgcolor="<?=$tbtopbgcolor?>" width="40%">
	<b>Skrivet av</b>
	</td>
	<td bgcolor="<?=$tbtopbgcolor?>" width="40%">
	<b>Senaste</b>
	</td>
	<td bgcolor="<?=$tbtopbgcolor?>" width="40%">
	<b>Svar</b>
	</td>
	</tr>
	<?php
		// Ladda in rader
		while($f=mssql_fetch_array($result))
		{
			$namn = $f["namn"];
			$epost = $f["epost"];
			$amne = $f["amne"];
			$text = $f["text"];
			$id = $f["id"];
			$ref_id = $f["ref_id"];
			$datum = $f["datum"];

			$raknasvar = mssql_num_rows( mssql_query("SELECT * FROM forum where ref_id = $id"));

			$dat = date('j/n H:i', strtotime($datum));

			// Varannan färg
			echo "<tr bgcolor='";
			if( $i++ % 2 == 0 ){
				echo $bg1;
			}else{
				echo $bg2;
			}
			echo "' valign=\"top\">\n";
			echo "<td><a href=\"svar.php?id=$id\"><u>$amne</u></a></td>\n";
			echo "<td>$namn</td>\n";
			echo "<td>$dat</td>\n";
			echo "<td align=\"center\">$raknasvar</td>\n";
			echo "</tr>\n";
			}
		
		// --- Sidnummer under listan. ---
		echo "<tr><td colspan=\"4\">";
		echo "<br />";
		echo $pagelinks;
		echo "</td></tr>";
	}
	mssql_close();
?>
addewebMedlem sedan jan. 2004216 inlägg
#12

Nu fungerar pagingen!!

// Med MSSQL
$query = "SELECT TOP $row_max * FROM forum WHERE id NOT IN
(SELECT TOP $row_start id FROM forum ORDER BY datum DESC) AND ref_id = 0 ORDER BY datum DESC";
137 ms totalt · 3 externa anrop · v20260731065814-full.29ac60f6
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
135 ms — hämta tråd, inlägg och bilagor (db)