Avatar billede Klaphattens Novice
03. juli 2012 - 22:34 Der er 12 kommentarer og
1 løsning

Hjælp til mysqli

Jeg prøver lige nu at finde ud af hvordan MySQLi skal bruges.

Jeg er startet med at prøve med eksemplerne på Update, Insert og Select fra oleboles artikel. dem kan jeg godt få til at virke.

Det er denne artikel jeg snakker om http://www.eksperten.dk/guide/1480

Nu vil jeg så prøve at få andre ting til at virke med MySQLi. i må ikke slå mig ihjel hvis jeg har postet dette spørgsmål det forkerte sted. vidste ikke om det var her eller i MySQL tråden det skulle postes. men jeg arbejder i php, så det blev her.

1.) RAND() - udtræk en eller flere tilfælde data fra en tabel.
Jeg har søgt på muligheder til at løse denne. men jeg finder bare frem til mange der spørger om hvordan det skal gøres, og aldig nogle svar.

2.) NOT IN - udtræk alle data i ´tabel1´, hvor data fra ´kolonne1´ NOT IN ´kolonne3´ i ´tabel2´.
Jeg har prøvet men ikke fået det til at virke.

3.) NOT IN - udtræk alle data i ´tabel1´, hvor data fra ´kolonne1´ NOT IN ´kolonne3´ i ´tabel2´ og where ´kolonne4´ i ´tabel2´ = 2.
Jeg kan ikke helt se hvordan man indsætte en where "kolonne4 i tabel2 = 2" i den.

4.) Blanding - Udtræk en eller flere tilfældige data fra ´tabel1´ hvor data fra ´kolonne1´ NOT IN ´kolonne3´ i ´tabel2´, og where ´kolonne4´ i ´tabel2´ = 2.
Da jeg ikke har kunne finde ud af 1, 2 og 3, kan jeg slet ikke sætte dem samme.

Hvert svar giver 30 point.
Avatar billede olebole Juniormester
03. juli 2012 - 23:03 #1
Der er sådan set ikke den store forskel på selve SQL- syntaksen - borset fra, at alle værdier er udskiftet med ?. En RAND SELECT kan du lave sådan:

$sql = 'SELECT FLOOR(RAND() * COUNT(*)) AS `rnd_foo_inx` FROM `foo`';
$stmt = $db->prepare($sql);
$stmt->execute();
$stmt->bind_result($rnd_foo_inx);
$stmt->fetch();
var_dump($rnd_foo_inx);
$stmt->close();

Her bindes værdien til en variabel, hvilket kan være en stor fordel i visse situationer. Ellers kan du bruge denne syntaks, som kan minde lidt mere om den gamle MySQL-syntaks:

$sql = 'SELECT FLOOR(RAND() * COUNT(*)) AS `rnd_foo_inx` FROM `foo`';
$stmt = $db->prepare($sql);
$stmt->execute();
$res = $stmt->get_result();
$row = $res->fetch_assoc();
var_dump($row['rnd_foo_inx']);
$res->free();
$stmt->close();
Avatar billede Klaphattens Novice
04. juli 2012 - 01:05 #2
Jeg har fået begge til at virke som de nok skulle. men de er lidt anderledes end det jeg er vant til.

Hvis vi nu siger at vi har kolonnerne ´id´ og ´navn´ og jeg gerne se 2 tilfældige id'er og deres tilhørende navne?

Er det rigtigt forstået hvis jeg siger, at jeg lige nu får jeg udskrevet float(x), hvor x er den valgte række. første række i tabellen er float(0), anden række float(1) osv.

Mit eget gæt er at jeg skal lave noget ala fetch_array, men jeg ved ikke helt hvordan jeg får lavet et bånd imellem fx id og float(2)

Jeg ved godt det ikke er float(2), men bare 2 jeg skal bruge. Det var bare for forklaringens skyld.
Avatar billede olebole Juniormester
04. juli 2012 - 03:12 #3
Der er mange langsomme måder at opnå det på. Det hurtigst afviklende er nok dette:

$sql = 'SELECT FLOOR(COUNT(*)*RAND()) AS `inx` FROM `foo`';
$res = $db->query($sql);
$row = $res->fetch_assoc();
$res->free();

$sql = 'SELECT `name` FROM `foo` LIMIT ?, 1';
$stmt = $db->prepare($sql);
$stmt->bind_param('i', $row['inx']);
$stmt->execute();
$res = $stmt->get_result();
$row = $res->fetch_assoc();
$res->free();
$stmt->close();
echo $row['name'];

I første kald skal vi ikke sætte parametre (og skal kun kalde én gang), så der kan vi nøjes med en alm. query. Ved andet kald bør derimod bruges et prepared statement
Avatar billede olebole Juniormester
04. juli 2012 - 03:17 #4
PS: Det er også den hurtigste måde i 'gammeldags' MySQL
Avatar billede tobrukDk Novice
04. juli 2012 - 03:52 #5
Det er næste det samme som de gammeldags men det er dog bare på en anden måde som man skal bygge det op på, jeg synes 100% klart at det er bedre og flotter sæt sammen!...
Avatar billede Klaphattens Novice
04. juli 2012 - 11:09 #6
Det ser ud til at være rigtigt.
Men der kommer en fejl jeg ikke lige kan gennemskue:


Fatal error: Call to a member function bind_param() on a non-object in C:\xampp\htdocs\fun\test.php on line 14

Linje 14 er denne:
$stmt->bind_param('i', $row['inx']);


Her er min kode:
$sql = 'SELECT FLOOR(COUNT(*)*RAND()) AS inx FROM test';
$res = $db->query($sql);
$row = $res->fetch_assoc();
$res->free();

$sql = 'SELECT name FROM test LIMIT ?, 1';
$stmt = $db->prepare($sql);
$stmt->bind_param('i', $row['inx']);
$stmt->execute();
$res = $stmt->get_result();
$row = $res->fetch_assoc();
$res->free();
$stmt->close();
echo $row['name'];
Avatar billede olebole Juniormester
04. juli 2012 - 13:13 #7
Kik på fejlens ordlyd, så kan du huske, hvad den betyder næste gang, du møder den. Den siger:

"Du har kaldt en funktion (bind_param), som ligger på et ikke-objekt"

Funktionen bind_param ligger jo normalt som metode på objektet, der udgør vores statement ($stmt->bind_param).  Altså har vi ikke noget statement objekt - altså må vores prepare være gået galt. Det er jo den, der skulle oprette vores statement objekt.

Måske, man kunne forestille sig, det kunne skyldes, at linjen (som du ikke viser):

$db = new mysqli(... ... ...);

- var gået galt. Men, så havde du tidligere fået samme fejl - bare med ordlyden:

"Fatal error: Call to a member function query() on a non-object in C:\xampp\htdocs\fun\test.php on line ???"
Funktionen query ligger nemlig som metode på $db, der jo er din objekt instans af klassen mysqli. Kan du se logikken?

Jeg har lige testet, og koden virker fint hos mig. Hvad sker der, hvis du skriver:

$sql = 'SELECT name FROM test LIMIT ?, 1';
$stmt = $db->prepare($sql);
echo $db->error;
exit();
Avatar billede Klaphattens Novice
04. juli 2012 - 16:14 #8
Fandt en meget dum fejl. man kan ikke altid se skoven for bare træer. men sådan er det jo nogen gange.

Det ser godt ud, men hvordan virker den der limit-del. jeg forstår det sådan at ? er den valgte række og , 1 er at det kun er et udtræk der vælges.

Hvis jeg nu vil have vist 2 tilfældige indlæg, der ikke ligger lige efter hinanden. Skal jeg så bare køre det 2 gange, eller kan man også gøre det smart.

Jeg har prøvet mig lidt frem med at indsætte while nogle steder hvor det ser logisk ud for mig, men det giver mig bare kun fejl.
Jeg prøvede så at lave den mere som den første løsning i #1, det lykkes, men jeg satte jo limit til 2, og så kom der 2 udtræk der efterfølger hinanden i databasen.

Jeg har også fået min 2'er med NOT IN til at virke. ved ikke hvad jeg gjorde galt inden jeg skrev spørgsmålet. jeg har dog ikke kunne kringle det andet NOT IN spørgsmål jeg havde (3'eren).

tubroDK jeg tror også jeg bliver glad for det når jeg bliver god til det.
Avatar billede olebole Juniormester
04. juli 2012 - 19:03 #9
Ja, du får to lige efter hinanden, hvis du sætter limit op til 2. Det vil nok betyde noget i 0.2 tilfælde ud af 1.000.000, du skal hente to 'tilfældige' rækker  *o)
Avatar billede Klaphattens Novice
05. juli 2012 - 14:02 #10
Sikke gode odds. jeg havde regnet med de var lavere ;o).

Men det svarede ikke på mine 2 spørgsmål. kan man lave så den finder 2 tilfælde der ikke er i rækkefølge, uden at køre scriptet 2 gange, eller skal man lave det som en funktion og køre det 2 gange. hvilket jo heller ikke er et problem. det er bare så jeg ved hvad man kan og ikke kan.

Og hvordan laver man mit spørgsmål 3?

Ole du må gerne smide et svar for det du er kommet med indtil nu.
Avatar billede olebole Juniormester
05. juli 2012 - 14:19 #11
Hvis du skal udtrække to rækker tilfældigt, skal du hverken bruge MySQL's RAND eller PHP's rand eller mt_rand. Ingen af dem giver nemlig et tilfældigt tal - men et pseudotilfældigt.

Hvis du vil se bort fra matematikken og bilde dig selv ind, der er tale om tifældige rækker, kalder du to gange. Er du mere realistisk, vælger du et pseudotilfældigt indgangspunkt og vælger to på hinanden følgende rækker  =)

3 løser du ligesom 2. Hvad er det præcist, du ikke kan finde ud af? Hvad prøver du, som ikke lykkes?

Ellers tak, jeg samler ikke point. Du lægger selv et svar og accepterer det, så tråden lukkes  =)
Avatar billede Klaphattens Novice
05. juli 2012 - 14:46 #12
Arrrrrgggghhhh det kostede næsten en computer.

Tak ole jeg tror at jeg har fattet det grundlæggende MySQLi.

Så vil jeg prøve lidt af de andre ting, såsom join og bagefter udskifter jeg dem i det jeg før har lavet.
Avatar billede olebole Juniormester
05. juli 2012 - 15:49 #13
*LoL* Jeg tager det som udtryk for opdagelsen af en fejl  :D

Tro mig, om to måneder vil du tænke tilbage i undren. Til den tid vil du måske tænke "Hold da kæft! Ole må have troet, jeg er en total klaphat!". Men nej, absolut ikke! Det har tværtimod været et hyggeligt gensyn med min egen forvirring, da jeg selv famlede rundt i mørket og ledte efter kontakten til loftlyset  =)

Når vi begynder på at lære noget nyt, tror jeg, vi har det med at genkende og forsøge at eftergøre nogle 'skriftbilleder' med tåget mening. Først senere begynder vi at læse og forstå, hvad der egentlig står - og så er det pludselig helt ufatteligt, at det nogensinde har givet problemer.

Om en måned eller to, når du har fået syntaksen ind under huden, er det ligeså let for dig at skrive og afvikle et prepared statement som at skrive en indkøbsseddel  *o)
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