Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Dzielenie Zapytania Na Strony
Forum PHP.pl > Forum > Bazy danych > MySQL
Fibolg
Wiem, że było masę razy, ale ta wyświetlająca petla while rozbija wszystkie moje próby powodując brak pomysłu na wykorzystanie jej do dopisywania zmiennych... Pomóżcie jakoś.... może jakaś podpowiedź?
Oto fragment skryptu:
  1. <?php
  2. include(&#092;"dbconf.php\");
  3. mysql_connect($hostname,$dbuser,$dbpassword);
  4. mysql_select_db($dbname);
  5. $zapytanie = &#092;"SELECT * FROM logowanie ORDER BY login ASC\";
  6. $wykonaj = mysql_query ($zapytanie);
  7.  
  8. $id=1;
  9. echo(&#092;"<table border=\"1\"> \");
  10. echo &#092;"<tr>
  11. <td width=&#092;"30px\" align=\"center\"><B>Lp.</B></td>
  12. <div style=&#092;"display: none\"><B>Id.</B></div>
  13. <td width=&#092;"200px\" align=\"center\"><B>Login</B></td>
  14. <td width=&#092;"150px\" align=\"center\"><B>Grupa</B></td>
  15. <td width=&#092;"100px\" align=\"center\"><B>Modyfikacja</B></td>
  16. <td width=&#092;"100px\" align=\"center\"><B>Usuwanie</B></td>
  17. </tr>&#092;";
  18.  
  19. while($wiersz=mysql_fetch_array ($wykonaj)) {
  20.     
  21.     $zapyt = &#092;"SELECT status FROM logowanie, kontrolne WHERE logowanie.kontrolne=kontrolne
    .
  22. d AND logowanie.login='\".$wiersz['LOGIN'].\"'\";
  23.     $wyk1 = mysql_query ($zapyt);
  24.     $wier1=mysql_fetch_array ($wyk1);
  25.     //echo($wier1[0]);
  26.     
  27.     $zapyt2 = \"SELECT barwa FROM kolory, kontrolne, logowanie WHERE kontrolne.kolor=kolory.
  28. d AND kontrolne.status='$wier1[0]'\";
  29.     $wyk2 = mysql_query ($zapyt2);
  30.     $wier2=mysql_fetch_array ($wyk2);
  31.     //echo($wier2[0]);
  32.  
  33. echo \"<tr>
  34. <td width=&#092;"30px\" align=\"right\">\".$id.\"</td>
  35. <div style=&#092;"display: none\">\".$wiersz['ID'].\"</div>
  36. <td width=&#092;"200px\"><font color=\"$wier2[0]\">&nbsp;\".$wiersz['LOGIN'].\"</font></td>
  37. <td width=&#092;"150px\"><font color=\"$wier2[0]\">&nbsp;\".$wier1[0].\"</font></td>
  38. <td width=&#092;"100px\" align=\"center\"><a href=\"users.php?stan=modyf&idmodyf=\".$wiersz['ID'].\"\">Modyfikuj</a></td>\";
  39. if ($wiersz['ID']!=1){ 
  40. echo &#092;"<td width=\"100px\" align=\"center\"><a href=\"users.php?stan=usun&idusun=\".$wiersz['ID'].\"\">Usuń</a></td>
  41. </tr>&#092;";} else{ echo \" <td width=\"100px\" align=\"center\">&nbsp;</td>\";}
  42.  
  43. $id++;
  44. }
  45. echo (&#092;"</table><BR>\");
  46. ?>


I jeszcze jedno pytanie... wiem, że są tam potrzebne dwie zmienne sterujące $od_ktorego i $co_ile. Chciałbym, żeby te i inne zmienne sterujące stroną były gdzieś zapisywane... Jak Wy sobie z tym radzicie?
1) Zapisujecie je normalnie w skypcie, a potem przy zmianie w nim grzebiecie?
Trochę to chyba nie teges, bo czasem można zrobić filtrowanie np. za pomocą combo i zmienna taka musi się zmieniać... czyli
2) Zapisywanie w pliku *.txt... też mnie nie przekonuje, nie po to używam bazy, żeby bawić się jeszcze w pliki tekstowe
3) W osobnej tabeli MySQL... No OK ale zawsze ta tabela będzie miała 1 (słownie: jeden) wiersz! (Chyba, że ktoś sobie pozapisuje konfiguracje rózne). Jak sobie z tym radzicie? Wchodzę właśnie w ten etap strony i nie wiem jak rozwiązać ten temat smile.gif
z góry Thx ogromne
Ace
poczytaj o

  1. LIMIT
Fibolg
wiem coś w stylu:
  1. $sql ="SELECT * FROM logowanie LIMIT $od_ktorego,$ile_na_strone";

ale chodzi o to, że trzeba tam zastosować pętlę, która będzie sprawdzała ilość wierszy itd. a mam juz jednego WHILE, który miesza mi szyki... gdzie ją zastosować? sadsmiley02.gif

===============================================
AAA ludzie pomóżcie coś bo dostaję białej gorączki sad.gif Nie działa mi sad.gif
Pianandrill
Nie możesz zrobić tego po prostu tak:
  1. SELECT * FROM logowanie ORDER BY login ASC LIMIT $start, $ile

a zliczyć wiersze tego zapytanie mozesz przez uzycie na resource mysql_num_rows. Jezeli chcesz policzyć wszystkich userów to
  1. SELECT count(*) FROM logowanie

i fetch'em wyciągasz ilość, także jako tablica zapisane.
Poza tym wewnątrz while'a masz chyba niepotrzebne zapytania. Zauważ ze dla kazdego logowania bedziesz mial dodatkowe 2 zapytania co raczej nie jest wydajne
Spróbuj przed pentlą wykonać te dwa zapytania umieszczając wszystko w tablicy asocjacyjnej gdzie kluczem jest login. Później w while sprawdzasz tylko:
  1. <?php
  2. if ( isset($wiersz['']) ) echo &#092;"Cośtam\"; else echo \"brak zmiennej\";
  3. ?>

tak mozna zrobić dla jednego i drugiego zapytania sprowadzając je do tablic które php szybciej przetwarza niż sql pobiera.

Z tymi zmiennymi sterującymi to nie bardzo wiem o co chodzi... chodzi ci o jakies porcjowanie? ale na podstawie czego?
Troszeczke wiecej opisz czego się spodziewasz to postaram sie w miarę możliwości odpowiedzieć.
Fibolg
Cytat
Poza tym wewnątrz while'a masz chyba niepotrzebne zapytania

Są potrzebne wszystkie. W petli While musi być za każdym wykonaniem jej nowe odwołanie do zapytania.
Ohh jutro się jeszcze pomęczę, ale nie mogę znaleźć jak na złość nawet jakiegoś porządnego przykładu w necie (tak to jest - jak człowiek nie szuka to się tego penta na pęczki). dry.gif
Cytat
Z tymi zmiennymi sterującymi to nie bardzo wiem o co chodzi...

Hmm wiem, że namieszałem smile.gif Ciężko mi zawsze powiedzieć o co mi chodzi. Dajmy na to masz sobie wyświetloną tablicę userów. U góry masz selecta, gdzie wybierasz jak ma filtrować... Wg Loginu, grupy, daty logowania... Wszystko ładnie, pięknie... ale gdzie zapisujesz te możliwości? W pliku txt, bazie? Czy użyć zwykłego Case? Jak tak, to gdzie i jak zapisać co akurat wybrał... Oh zakręciłem się już sam snitch.gif Chodzi ogólnie o wszystkie ustawienia strony, które zmieniać może sam user np w spoosobie jej wyświetlania.
Parti
Cytat(Fibolg @ 2004-09-06 21:31:52)
Są potrzebne wszystkie. W petli While musi być za każdym wykonaniem jej nowe odwołanie do zapytania.

Zaryzykuje stwierdzenie, że dało by się w jednym zapytaniu wyciągnąć wszystko co potrzeba. Być może wycofam sie z tego. Podaj dokładnie co chcesz uzyskać oraz struktury tabel. Dodatkowo jak podajesz fragmenty swoich skryptów to usuwaj takie rzeczy jak:
  1. <?php
  2. echo &#092;"<td width=\"30px\" align=\"center\"><B>Lp.</B></td>
  3. <div style=&#092;"display: none\"><B>Id.</B></div>
  4. <td width=&#092;"200px\" align=\"center\"><B>Login</B></td>
  5. <td width=&#092;"150px\" align=\"center\"><B>Grupa</B></td>
  6. <td width=&#092;"100px\" align=\"center\"><B>Modyfikacja</B></td>
  7. <td width=&#092;"100px\" align=\"center\"><B>Usuwanie</B></td>
  8. </tr>&#092;";
  9. ?>

To całe formatowanie jest mało czytelne.
Pianandrill
Są potrzebne? no to patrz:
zapytania:
  1. <?php
  2. $res1 = mysql_query (&#092;"SELECT * FROM logowanie ORDER BY login ASC\");
  3. while($wiersz1=mysql_fetch_assoc ($res1)) //uzywaj assoc jezeli kozystasz tylko z assoc
  4. {
  5. $loginy[$wiersz['login']] = $wiersz;  //dzieki temu masz tablice do ktorej odwolujesz sie przez login
  6. }
  7.  
  8. $res2 = mysql_query (&#092;"SELECT status, id, kolor FROM logowanie l, kontrolne k WHERE l.kontrolne=k.
    i
  9. \");
  10. while($wiersz2=mysql_fetch_assoc ($res2)) 
  11. {
  12. $status[wiersz['id']] = $wiersz;  
  13. }
  14.  
  15. $res3 = mysql_query (\"SELECT barwa, id FROM kolory, kontrolne WHERE kontrolne.kolor=kolory.id\");
  16. while($wiersz3=mysql_fetch_assoc ($res2)) 
  17. {
  18. $barwa[wiersz['id']] = $wiersz['barwa'];  
  19. }
  20. ?>

Teraz mamy 3 tablice: $loginy, $status, $barwa. Zamiast wykonywać za kazdym razem po 2 dodatkowe zapytania dla kazdego loginu przeszukaj tablice pod kontem odpowiedniej zmiennej.
  1. <?php
  2.  
  3. if ($loginy) 
  4. {
  5.  foreach ($loginy as $login)
  6. {
  7.  if ( isset($status[$login['kontrolne']]) )
  8.  {
  9. $status_logowania = $status[$login['kontrolne']]['status'];
  10. foreach($status as $s) 
  11.  { 
  12. if ( isset($barwa[$s['kolor']] && $s['status'] == $status_logowania ) $kolor = $barwa[$s['kolor']];
  13.  }
  14.  } else $statys_logowania = 'Nieznany';  
  15.  //tutaj wyświwetlasz rząd tabelki korzystając z aktualnych zmiennych $login['login'], $status_logowania oraz $kolor
  16. }
  17. } else echo &#092;"brak userów\"
  18.  
  19. ?>

Teraz masz dla kazdego loginu ustawione zmienne $statys_logowania i $kolor. Oczywiescie wewnątrz pętli foreach( $loginy as $login ) musisz umieścić kod tabelki i zmienne ww wyświetlać w odpowiednim miejscu danego rzędu.
Takie rozwiązanie jest dużo szybsze i na pewno lepsze, jeżeli chcesz uzyc LIMIT to pamietaj ze tylko na tabeli logowanie inaczej wyjdą głupoty.
PS:
  1. SELECT barwa FROM kolory, kontrolne, logowanie WHERE kontrolne.kolor=kolory.id AND kontrolne.STATUS='$wier1[0]'
- po co tutaj tabela logowanie?
Nie jestem pewien ale masz chyba troszkę burdel w relacji. Jeżeli pokażesz strukturę tych tabelek z krótkim opisem co w nich przechowujesz to powiem dlaczego mi się tak wydawalo.
Od razu mówię, ze nie sprawdzalem tego czy to dziala, pisalem z glowy z ww. powodu (nie znam struktury tabelki) więc pewnie odrobinkę będziesz musial może to zmodyfikować. ale ogólna zasada jest pokazana.
Fibolg
Pianandrill, dzięki za zainteresowanie tematem... Wiesz co do burdelu to rzeczywiście - mam nie tylko w skryptach smile.gif Wiesz dopiero zaczynam zajmować się php tak na dobre i wziąłem się za skrypt logowania, który będzie odpowiadał moim potrzebom. Dlatego mam tabele jak w skrypcie:
  1. CREATE TABLE IF NOT EXISTS LOGOWANIE (
  2. ID SMALLINT(6) NOT NULL AUTO_INCREMENT,
  3. LOGIN VARCHAR(20) NOT NULL,
  4. HASLO VARCHAR(32) NOT NULL,
  5. KONTROLNE SMALLINT(2) NOT NULL,
  6. PRIMARY KEY (ID),
  7. UNIQUE KEY ID (ID)
  8. );
  9.  
  10. CREATE TABLE IF NOT EXISTS KONTROLNE (
  11. ID SMALLINT(6) NOT NULL AUTO_INCREMENT,
  12. STATUS VARCHAR(25) NOT NULL,
  13. KOLOR SMALLINT(2) NOT NULL,
  14. PRIMARY KEY (ID),
  15. UNIQUE KEY ID (ID)
  16. );
  17.  
  18. CREATE TABLE IF NOT EXISTS KOLORY (
  19. ID SMALLINT(6) NOT NULL AUTO_INCREMENT,
  20. BARWA VARCHAR(25) NOT NULL,
  21. OPIS VARCHAR(25) NOT NULL,
  22. UNIQUE KEY ID (ID)
  23. );
  24.  
  25. INSERT INTO LOGOWANIE(ID, LOGIN, HASLO, KONTROLNE) VALUES (0, "admin", "1a1dc91c907325c69271ddf0c944bc72", 1);
  26. INSERT INTO KONTROLNE(ID, STATUS, KOLOR) VALUES (1, "Administrator", 2);
  27. INSERT INTO KONTROLNE(ID, STATUS, KOLOR) VALUES (2, "Użytkownik", 1);
  28. INSERT INTO KOLORY(ID, BARWA, OPIS) VALUES (1, "black", "Czarny");
  29. INSERT INTO KOLORY(ID, BARWA, OPIS) VALUES (2, "red", "Czerwony");

Kilka słów wyjaśnienia: tabela logowanie to tablica userów. W głównym zamyśle to admin ma jedynie możliwość zakładania kont userów, którzy podzieleni będą na grupy. Np grupa Administrator będzie miała dostęp do wszystkich opcji, grupa Użytkownik, do określonych, moderator do określonych... Wszystko później chcę oprzeć na sesjach. Grupę usera sprawdza pole kontrolne w tablicy logowanie. Za pomocą relacji jeden - wielu sprawdzam jaka to grupa, zaś jeden do wielu grupa/kolor sprawdzam jej kolor... i tyle.
Co do porządku skryptu, to narazie jestem na etapie zrobienia, żeby działało smile.gif Może jak się trochę wprawię, to będę tworzył takie pętle w pętlach itd, a idea tablic assocjacyjnych zostanie na pewno przeze mnie przemyślana.

Z góry dziękuję za pomoc, ale może jeszcze pomożesz krok dalej i powiesz w którym miejscu tego Twojego skryptu zrobić odwołanie do stron userów?
<-- [1] 2 3 ... -->
Parti
Jeśli dobrze zrozumiałem to chcesz uzyskać listę użytkowników wraz ze statusem z tablicy KONTROLNE oraz barwą z tablicy KOLORY.
  1. SELECT L.id, L.login, KON.STATUS, KOL.barwa, KOL.opis FROM LOGOWANIE AS L, KONTROLNE AS KON, KOLORY AS KOL WHERE L.kontrolne = KON.id AND KON.kolor = KOL.id
qtchb
Pokażę Ci, jak ja to rozwiązałem

Jestem jeszcze lamerem jeśli chodzi o php, ale z tym udało mi się i myślę, że sposób jest w miarę prosty.

Stworzyłem dwa identyczne pliki. W pierwszym select wybiera pierwszą partię rekordów z mysql, w drugim pliku pozostałe partie.

****W pierwszym pliku****
Zdefiniowałem dwie zmienne:
$limit = 30;
$limit0 = ($limit - 30);

W poleceniu SELECT wstawiłem zakres danych:
  1. $sql = "select *
  2. from k_ksiazki WHERE id_ksiazki
  3. BETWEEN $LIMIT 0 AND $limit";


Potem wstawiłem link do strony drugiej:
  1. <?php
  2.  
  3. echo &#092;"<a href=\"modules.php?op=modload&name=Listak&file=lista2&limit=$limit\"> tutaj.</a>\";
  4.  
  5. ?>


(Strona jest modułem CMSa.)

****W drugim pliku****
Zdefiniowałem zmienne:
$limit1 = ($limit + 30);
$limit0 = (limit1 - 30);

Polecenie SQL w tym pliku wygląda tak:
  1. $sql = "select *
  2. from k_ksiazki WHERE id_ksiazki
  3. BETWEEN $LIMIT 0 AND $LIMIT 1 ";


Potem jeszcze link do tej samej strony, ale przy limit=$limit1
  1. <?php
  2.  
  3. echo &#092;"<a href=\"modules.php?op=modload&name=Listak&file=lista2&limit=$limit1\"> tutaj.</a>\";
  4.  
  5. ?>


Nie jest to może zbyt piękne i eleganckie, ale działa i jest proste w użyciu.
Poza tym wykorzystuję też zmienne w treści strony, żeby poinformować użytkowników, jakie rekordy są aktualnie wyświetlane.
  1. <?php
  2.  
  3. echo &#092;"Aktualnie wyświetlane są książki o numerze grzbietowym od <b>$limit0</b> do <b>$limit1</b>. Aby wyświetlić kolejne 30 książek, kliknij\";
  4.  
  5. ?>


Pozdr
Pianandrill
Tak jak myślalem masz o jedną tabelkę za dużo. Upewnij się ze potrzebujesz tabelki kolory, po co przechowywać to w osobnej tabelce
  1. $sql = "select *
  2. from k_ksiazki WHERE id_ksiazki
  3. BETWEEN $LIMIT 0 AND $limit";


ten sposób na pewno nie jest dobry chociazby z tego powodu, ze nie pozwala na wyswietlanie równej ilości ksiązek na kazdej stronie. Co sie stanie jak 20 ksiązek zostanie usunięte? id bedą nieuzywane a brane pod uwagę. Może sie zdazyc ze bedziesz mial 2 strony puste!

Musisz zdefiniować dwie wartości: $strona i $stron.
Wartość $strona możesz opbrac np. z linka a jeżeli w linku nic niema to strona = 1 (lub ostatnia ale to pozniej)
Zmienną $stron definiujesz zliczając np. funkcją mysql_num_rows('Select count(id) from ksiazki'); pozniej wyciagając z tamtąd zwróconą liczbę robisz tak:
  1. <?php
  2. $stron = ceil($ilosc_rzedow / $max) //$max oznacza ilosc elementow na stronie, można ją pozniej latwo zmieniać
  3. ?>

Mamy już wartosc $stron i $strona (aktualna). Okreslic trzeba teraz dla zapytania od którego elementu ma pobrac dane:
  1. <?php
  2. $start = ($strona - 1) * $max;
  3. ?>

zaytanie wyglada tak:
  1. SELECT * FROM ksiazki WHERE (costam) LIMIT $start, $max

teraz wynik zapytania zawiera tylko te krotki które mają być wyswietlone na stronie
Przechodzimy do tworzenia linków
  1. <?php
  2.  
  3. if ($stron > 1)
  4. {
  5. $nav = (($strona == 1)?' << ':' <a href=index.php?id=ksiazki&s='.($strona-1).'><<</a> ').' ';
  6. for($i=1; $i<=$stron; $i++)
  7. $nav.= (($i == $strona)?' ['.$i.'] ':' <a href=index.php?id=ksiazki&s='.$i.'>['.$i.']</a> ');
  8. $nav.= ' '.(($strona == $stron)?' >> ':' <a href=index.php?id=ksiazki&s='.($strona+=1).'>>></a> ');
  9. echo $nav;
  10. }
  11. ?>


Ustalenie ilości wierszy możesz wykonać przed tworzeniem tablic userów i calej reszty. Ten warunek wyrzej umieść tam gdzie ma być menu nawigacyjne. Możesz to zrobić przed wyswietlaniem wpisów albo po. Albo jedno i drugie. Po wykonaniu tego warunku masz już zmienną $nav wiec możesz drugi raz tylko sprawdzić czy nie jest ona pusta i wyświetlić ją - żeby nie liczyć ponownie tego samego.
Jeżeli jest tylko 1 strona to nawigacja się nie wyswietli bo po co?
Dodatkowo link do aktualnej strony jest nieaktywny, bo po co? biggrin.gif
Po prawej i lewej stronie sa linki do nastepnej i poprzedniej strony.
Pozostaje jeszcze na pewno kilka kwesti do przemyslenia, jak np. co zrobic kiedy okazuje się ze mamy 40 stron? takie menu nawigacyjne jest nieczytelne. Ale z tym tez raczej niema problemu.
Cytat
Grupę usera sprawdza pole kontrolne w tablicy logowanie. Za pomocą relacji jeden - wielu sprawdzam jaka to grupa, zaś jeden do wielu grupa/kolor sprawdzam jej kolor...


Czyli zakladasz ze jeden user może być przypisany do kilku grup, ok., ale dlaczego zakladasz ze kolor może być przypisany rózny dla kazdej grupy? chyba ze do czegos innego wykorzystujesz jeszcze tabele kolor.
Zastanów się czy nie wystarczy ze w tabeli kontrolne (może łatwiej będzie ją nazwać grupa albo uprawnienia) zdefiniować dla kazdej grupy kolor. W końcu nie kolor definiuje grupę (chyba) albo usera... bo tez nie wiem.
Pewnie nie wyczerpałem wszystkich możliwości, jak coś jest jeszcze nie jasne to pisz.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.