Avatar billede swaq Nybegynder
02. januar 2004 - 23:29 Der er 17 kommentarer og
1 løsning

traversering der ordner tal

Hejsa

Min hjerne er vist brændt lidt sammen, for det her volder mig lidt for mange problemer - men det er jo oz sent og nytårs aften sidder stadig i baghovedet...

Anyways, here goes:
Jeg har lavet en venteliste til min andelsboligforening i php (gad ikke skrive 78 adresse sedler i hånden, så nu ordner puteren det...)
I min tabel findes feltet "nr" som er en int. Den første person i listen har "nr == 1" og så fremdeles...
Mit problem er at få lavet en funktion som ser nogenlunde sådan ud:
function fixList($nr){
  $sql = "select nr from liste";
  //nr == det nummer som er fjernet fra listen. e.g. 33
  pseudokode:
  fra $nr sæt: $nyt_nr = ($nr + 1) //e.g. bliver personen på plads 34 nu sat på plads 33
  dvs. noget med: "update liste set nr = '$nyt_nr' WHERE nr = '$nr'";
  forsæt indtil listen er tom
  $nr++; //da næste i rækken nu må være 34

}

Håber I kan gennemskue min pseudokode, men jeg er sku' kørt lidt fast i hvordan det gøres på den smarteste måde...
Ovenstående resulterer i adskillige kald til databasen... kan det gøres i et kald (SQL)???
Avatar billede tefcke Nybegynder
03. januar 2004 - 00:12 #1
Aner ikke om det er muligt, men kan man ikke bare opdatere alle poster i databasen som har nummer højere end (f.eks.) 33

Altså:
UPDATE liste
SET nr = nr + 1
WHERE nr > 33
Avatar billede tefcke Nybegynder
03. januar 2004 - 00:15 #2
skulle nok have været SET nr = nr - 1
Denne funktion skal vel så kaldes hver gang der bliver fjernet en fra databasen
Avatar billede olebole Juniormester
03. januar 2004 - 02:19 #3
<ole>

swag >> Hvorfor gøre sådan? Hvorfor ikke bare give dem et fortløbende nummer (autonummerering i MySQL) - og så sortere efter nummeret, når du henter fra databasen? Så har du dem altid i den rigtige rækkefølge, selvom nogle skulle være slettet  :)

/mvh
</bole>
Avatar billede swaq Nybegynder
03. januar 2004 - 03:29 #4
--> Ole: true, true, men jeg vil gerne, eller dvs. dem der står på listen vil gerne, vide hvilken placering de har - hence deres nr i tabellen, derfor er det vigtigt, at "nr" altid er up-2-date.
Avatar billede swaq Nybegynder
03. januar 2004 - 03:59 #5
--> tefcke: umiddelbart er din løsning den samme som den jeg havde i tankerne, problemet er blot, at der opstår følgende fejl: #1062 - Duplicate entry '5' for key 1

Det pudsige er, at fejlen opstår forskellige steder, har oplevet at det i en tabel med 71 numre først gik galt ved nr 48 - meget mærkeligt!
Avatar billede swaq Nybegynder
03. januar 2004 - 04:02 #6
det hjælper ikke at re-connecte til databasen (havde håbet den måske ville flushe den tidligere record, således duplikatet ungås - hvis altså det er det der er problemet...
Avatar billede olebole Juniormester
03. januar 2004 - 04:30 #7
swag >> Det er da noget vrøvl - du kan ligeså let give dem nummeret, når du bladrer record-settet igennem. Det er den måde resten af verden gør det på ... og det er der nok mere end én god grund til, skal du se  ;o)
/mvh
Avatar billede swaq Nybegynder
03. januar 2004 - 04:37 #8
hehe... nu jorder jeg dig lige ole, for det kan faktisk lade sig gøre i mysql version 4.0.0+
Se bare her: http://www.mysql.com/newsletter/2003-09/a0000000224.html

Løsningen på problemet er:
UPDATE liste SET nr = nr - 1 WHERE nr > $nr ORDER BY nr ASC;

Men jeg er da tilbøjelig til at give dig ret alligevel :O) Hvilket får mig til at tænke på en anden lille detalje, nemlig spørgsmålet om hvilken teknik der egner sig bedst til kommunikation med databasen...
1. Åbne/lukke i samme sekund man fyre en mysql_query(...) af
2. Åbne først lave x antal mysql_query(...), lukke

2 egner sig vel bedst i en løkke... ellers bliver det vældigt mange åbne/lukke kald...
Avatar billede swaq Nybegynder
03. januar 2004 - 04:37 #9
Hov, jeg svarede sku' selv på det... hvis der er nogen der vil have point for deres indsats her må I lige sige til - Lukker snart :O)

Tak for hjælpen!
Avatar billede olebole Juniormester
03. januar 2004 - 05:14 #10
Ehhh ... så må jeg vist slå ordet 'jorde' op ...?!!???

Naturligvis kan man (ekstremt sjældent) få brug for at opdatere en MySQL-tabel på denne måde - men det har du overhovedet ikke brug for.

$sql = "SELECT `navn` FROM `TABELNAVN` ORDER BY `nr`";
$res = mysql_query( $sql );
$inx = 0;
while ( $row=mysql_fetch_assoc($res) ) {
  $inx++;
  $str .= $row["navn"]." er nummer: ".$inx."<br>\n";
}
print $str;

Det er det hele, du har brug for.
Hvad angår connections, så nøjes med én - og foretag så dine forespørgsler. Du behøver ikke at lukke den igen. Den lukker automatisk, når scriptet er kørt færdigt.
/mvh
Avatar billede tefcke Nybegynder
03. januar 2004 - 13:05 #11
ORDER BY nr ASC
Ahhh, klart klart, ellers er der jo chance for at du for dubletter (hvis 'nr' altså er primary eller unique) ... godt du fandt ud af det!
Avatar billede olebole Juniormester
03. januar 2004 - 18:12 #12
Det ændrer ikke ved, det er en grundlæggende misforståelse af MySQL at begynde at lave den slags 'oprytninger' i denne slags situationer. Hvorfor overhovedet gøre det?
Avatar billede Slettet bruger
03. januar 2004 - 20:47 #13
Hvorfor ikke lave en tæller når listen udskrives til skærmen, som starter på 1, og så stiger efterhånden som personerne listes.

$query_antal = mysql_query("SELECT COUNT(*) FROM TABELNAVN");

if (mysql_result(($query_antal),0) < 1)
  {
    // Fejl... ingen navne i tabellen...
  }
else
  {
    $query_navne = mysql_query("SELECT navn FROM TABELNAVN ORDER BY nr ASC");

    $i_venteliste = 0;
    while ($row_navne = mysql_fetch_assoc($query_navne))
      {
      echo $i_venteliste." - ".$row_navne['navn']."<br>";
      $i_venteliste ++;
      }
  }

Så slipper du for at skulle lave andet end at slette folk i tabellen.....
Avatar billede olebole Juniormester
03. januar 2004 - 20:53 #14
kfisker >> Ehhh ... der er vel ingen grund til at lave det mindre effektivt, end det allerede er foreslået (03/01-2004 05:14:21). Dit første SQL kald er helt overflødigt  :)
/mvh
Avatar billede Slettet bruger
03. januar 2004 - 20:57 #15
olebole...> Nej, med mindre du gerne vil have en anden besked på skærmen, såfremt der ikke er nogle oprettet i tabellen.

Om man så vil bruge en if-sætning eller en count direkte i tabellen er vel en smagssag.......
Avatar billede olebole Juniormester
03. januar 2004 - 21:48 #16
Nej, det er et spørgsmål om effektivitet. Man søger _altid_ at foretage så få kald til databasen, som overhovedet muligt:

<?
$sql = "SELECT `navn` FROM `TABELNAVN` ORDER BY `nr`";
$res = mysql_query( $sql );
if ( mysql_num_rows($res)<1 ) {
    // Intet fundet
}
$inx = 0;
while ( $row=mysql_fetch_assoc($res) ) {
  $inx++;
  $str .= $row["navn"]." er nummer: ".$inx."<br>\n";
}
print $str;
?>

... og så kan du sortere 'ASC' eller 'DESC', som du ønsker - men det ene kald er yderst vigtigt.
/mvh
Avatar billede olebole Juniormester
03. januar 2004 - 21:49 #17
... og du kan naturligvis lægge udskrivningen i en 'else' - hvis du synes  :)
Avatar billede swaq Nybegynder
22. maj 2004 - 01:04 #18
lukker
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester