Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Prepared statements - løkke inde i en anden løkke

79 views
Skip to first unread message

Philip Nunnegaard

unread,
Jul 22, 2012, 4:33:35 PM7/22/12
to
Jeg er jo f�r blevet bel�rt om at prepared statements er vejen frem, s�
havde egentlig t�nkt mig at fors�ge mig med det nu.

Det gik fint, n�r jeg vare brugte en simpel sql-s�tning baseret p� denne
side:
http://www.eksperten.dk/guide/1480

Men n�r jeg s� inde i den l�kke det giver vil tilgribe en anden tabel,
g�r det galt. Den ser ud til helt at ignorere at den skal kigge i denne
anden tabel.

Kodesnippen kan ses her:
http://www.hitsurf.dk/privat/phptest.txt

Det g�r fint med at hente variablerne fra den f�rste tabel: $pid,
$overskrift, $tekst og $dato.

Men n�r jeg s� skal ind i tabellen "brugere" (for at se hvilket
brugernavn der h�rer til det p�g�ldende bruger-id), henter den ingenting.
Den echo "<p>---</p>"; som jeg har indsat i den l�kke echoes slet ikke,
hvilket for mig tyder p� at den slet ikke kommer ind i det if-statement.

Kan nogle se hvad jeg g�r forkert.

Og ja! Jeg HAR fors�gt at google det.

--
Philip

Philip Nunnegaard

unread,
Jul 22, 2012, 4:47:19 PM7/22/12
to
Den 22-07-2012 22:33, Philip Nunnegaard skrev:

[snip noget om prepared statements]

Det h�rer muligvis hjemme i databasegruppen, men jeg tror mere at det er
noget php-kode jeg ikke forst�r ordentligt.

Jeg ved fx heller ikke hvad "->" betyder.

--
Philip

Stig Johansen

unread,
Jul 23, 2012, 1:41:54 AM7/23/12
to
Philip Nunnegaard wrote:

> Den 22-07-2012 22:33, Philip Nunnegaard skrev:
>
> [snip noget om prepared statements]
>
> Det h�rer muligvis hjemme i databasegruppen, men jeg tror mere at det er
> noget php-kode jeg ikke forst�r ordentligt.

Det er det ogs�.

Parametre angives med ? som du ogs� kan se i din henvisning.

Denne s�tning:
if ($stmt1 = $mysqli->prepare('select navn from brugere where id=pid')) {
s�ger p� id=pid, hvilket egentlig burde give en fejl fra databasen, da pid
ikke er en parameter, ej eller et tal.

Skulle nok hedde:
if ($stmt1 = $mysqli->prepare('select navn from brugere where id=?')) {

> Jeg ved fx heller ikke hvad "->" betyder.

Det er en pointer i c-syntax.

--
Med venlig hilsen
Stig Johansen

Birger Sørensen

unread,
Jul 23, 2012, 4:00:18 AM7/23/12
to
Philip Nunnegaard kom med fᅵlgende:
> Den 22-07-2012 22:33, Philip Nunnegaard skrev:
>
> [snip noget om prepared statements]
>
> Det hᅵrer muligvis hjemme i databasegruppen, men jeg tror mere at det er
> noget php-kode jeg ikke forstᅵr ordentligt.
>
> Jeg ved fx heller ikke hvad "->" betyder.

//Henter brugernavn
if ($stmt1 = $mysqli->prepare('select navn from brugere where id=pid'))
$stmt1->bind_param('i', $id);
$id = $pid;
$stmt1->execute();
$stmt1->bind_result($navn);

Som Stig siger, skal det formentlig vᅵre
if ($stmt1 = $mysqli->prepare('select navn from brugere where id=?'))
og bᅵr svjks derefter virke efter hensigten.

$mysqli og $stmt er objekter. De har bᅵde vᅵrdier og funktioner
"indbygget".
Man bruger notationen -> til at kalde objekters funktioner/lᅵse
vᅵrdier. F.eks. kalder $stmt->fetch() $stmt objektets fetch() funktion,
og $stmt->errno lᅵser fejlkode og $stmt->num_rows giver antallet af
rᅵkker i sidste forespᅵgsel.

Birger
$stmt

--
http://varmeretter.dk - billig, sund og hurtig mad
Utils http://sdccms.dk/ordbog/ http://sdccms.dk/mailfriend/


Philip Nunnegaard

unread,
Jul 23, 2012, 6:05:31 AM7/23/12
to
Den 23-07-2012 10:00, Birger Sᅵrensen skrev:

> Som Stig siger, skal det formentlig vᅵre
> if ($stmt1 = $mysqli->prepare('select navn from brugere where id=?'))
> og bᅵr svjks derefter virke efter hensigten.

Det gᅵr det sᅵ ikke.
Har rettet kodesnippen mellem //Henter brugernavn og //Slut pᅵ
brugernavn til:

if ($stmt1 = $mysqli->prepare('select navn from profil where id=?')) {
$stmt1->bind_param('i', $id);
$id = $pid;
$stmt1->execute();
$stmt1->bind_result($navn);
while ($stmt1->fetch()) {
$pnavn = $navn;
}
$stmt1->close();
echo "---";
}


Jeg har ogsᅵ forsᅵgt at ᅵndre

while ($stmt1->fetch()) {
$pnavn = $navn;
}


til

$pnavn = $navn;

Begge dele uden held.

> sqli og $stmt er objekter. De har bᅵde vᅵrdier og funktioner
> "indbygget".

Det er nok det der med objekter der er problemet. Jeg forstᅵr ikke
konceptet. Jeg har fx svᅵrt ved at forstᅵ hvordan en variabel pludselig
kan blive lig med en funktion, sᅵdan som man ser det i denne linje:

if ($stmt1 = $mysqli->prepare('select navn from profil where id=?'))

> Man bruger notationen -> til at kalde objekters funktioner/lᅵse vᅵrdier.
> F.eks. kalder $stmt->fetch() $stmt objektets fetch() funktion, og
> $stmt->errno lᅵser fejlkode og $stmt->num_rows giver antallet af rᅵkker
> i sidste forespᅵgsel.

Det giver lidt mening.

--
Philip

Birger Sørensen

unread,
Jul 23, 2012, 9:29:11 AM7/23/12
to
Philip Nunnegaard tastede fᅵlgende:
> Den 23-07-2012 10:00, Birger Sᅵrensen skrev:
>
>> Som Stig siger, skal det formentlig vᅵre
>> if ($stmt1 = $mysqli->prepare('select navn from brugere where id=?'))
>> og bᅵr svjks derefter virke efter hensigten.
>
> Det gᅵr det sᅵ ikke.
> Har rettet kodesnippen mellem //Henter brugernavn og //Slut pᅵ brugernavn
> til:
>
> if ($stmt1 = $mysqli->prepare('select navn from profil where id=?')) {
> $stmt1->bind_param('i', $id);
> $id = $pid;
> $stmt1->execute();
> $stmt1->bind_result($navn);
> while ($stmt1->fetch()) {
> $pnavn = $navn;
> }
> $stmt1->close();
> echo "---";
> }

Prᅵv evt
$id = $pid;
$query1 = "SELECT navn FROM profil WHERE id=?";
if (($stmt1 = $mysqli->prepare($query1)) &&
$stmt1->bind_param('i', $id) &&
$stmt1->execute() &&
$stmt1->bind_result($navn) {
while ($stmt1->fetch()) {
$pnavn = $navn;
}
$stmt1->close();
echo "---";
...
}
else {
echo $mysqli->error;
}
Det burde vist nok fortᅵlle hvorfor det gᅵr galt...

>
> Jeg har ogsᅵ forsᅵgt at ᅵndre
>
> while ($stmt1->fetch()) {
> $pnavn = $navn;
> }
>
>
> til
>
> $pnavn = $navn;
>
> Begge dele uden held.

Det fᅵrste er rigtigt.
execute() udfᅵrer prepare funktionen, men leverer ikke noget resultat
(ud over sand hvis OK og falsk hvis der optrᅵder fejl): resultatet skal
hentes med fetch()

>> sqli og $stmt er objekter. De har bᅵde vᅵrdier og funktioner
>> "indbygget".
>
> Det er nok det der med objekter der er problemet. Jeg forstᅵr ikke konceptet.
> Jeg har fx svᅵrt ved at forstᅵ hvordan en variabel pludselig kan blive lig
> med en funktion, sᅵdan som man ser det i denne linje:
>
> if ($stmt1 = $mysqli->prepare('select navn from profil where id=?'))

prepare funktionen returnerer et object. Sᅵ $stmt1 er et object - ikke
en funktion.

>
>> Man bruger notationen -> til at kalde objekters funktioner/lᅵse vᅵrdier.
>> F.eks. kalder $stmt->fetch() $stmt objektets fetch() funktion, og
>> $stmt->errno lᅵser fejlkode og $stmt->num_rows giver antallet af rᅵkker
>> i sidste forespᅵgsel.
>
> Det giver lidt mening.

Har lidt travlt lige nu.
Prᅵv og vend tilbage...

Birger

Anders Wegge Keller

unread,
Jul 23, 2012, 9:49:52 AM7/23/12
to
Birger Sørensen <s...@bbsorensen.com> writes:

> Prøv evt

Og hvis det ikke giver noget brugbart, så kald

mysql_report(MYSQLI_REPORT_ALL);

Inden nedenstående kode, og pak den inde i en try-catch, hvor du
fanger mysqli_sql_exception. Hvis du får for meget brok over indexer,
kan du ændre konstanten til MYSQLI_REPORT_ERROR i stedet.

> $id = $pid;
> $query1 = "SELECT navn FROM profil WHERE id=?";
> if (($stmt1 = $mysqli->prepare($query1)) &&
> $stmt1->bind_param('i', $id) &&
> $stmt1->execute() &&
> $stmt1->bind_result($navn) {
> while ($stmt1->fetch()) {
> $pnavn = $navn;
> }
> $stmt1->close();
> echo "---";
> ...
> }
> else {
> echo $mysqli->error;
> }

--
/Wegge

Leder efter redundant peering af dk.*,linux.debian.*

Philip Nunnegaard

unread,
Jul 23, 2012, 10:07:10 AM7/23/12
to
Birger Sᅵrensen skrev:

> Prᅵv evt
(...)
> else {
> echo $mysqli->error;
> }
> Det burde vist nok fortᅵlle hvorfor det gᅵr galt...

Det gav i hvert fald en fejlmeddelelse:

"Commands out of sync; you can't run this command now"

--
Philip

Philip Nunnegaard

unread,
Jul 23, 2012, 4:33:16 PM7/23/12
to
Den 23-07-2012 16:07, Philip Nunnegaard skrev:

> Det gav i hvert fald en fejlmeddelelse:
>
> "Commands out of sync; you can't run this command now"

Det ser ud til at problemet er lᅵst.

Prᅵver jeg at ᅵndre $mysqli til $mysqli1, fᅵr jeg at vide at funktionen
ikke kan kᅵres pᅵ et non-object.

Jeg tᅵnkte om lᅵsningen er at oprette objektet $mysqli1.

Sᅵ lᅵsningen var at indsᅵtte nedenstᅵende linje lige fᅵr

if ($stmt1 = $mysqli1->prepare... (bemᅵrk $mysqli er ᅵndret til $mysqli1).

Lige over dette if-statement oprettes objektet $mysqli1:

$mysqli1 = new mysqli("servernavn", "databasebruger", "kode",
"databasenavn");

Sᅵ virker det som ᅵnsket.

--
Philip

Birger Sørensen

unread,
Jul 23, 2012, 5:45:53 PM7/23/12
to
Philip Nunnegaard kom med denne ide:
Du arbejder sᅵ med 2 forbindelser til databasen. Og det er vel ogsᅵ
godt nok ;>)
Problemet er, at mysqli ikke kan arbejde med mere end een prepared
statement, sᅵ det gᅵr galt nᅵr du bruger fetch() i begge lᅵkker.
Eftersom du bruger pid fra det fᅵrste udtrᅵk, kan du i anden lᅵkke
nᅵjes med en almindelig query - under forudsᅵtning af det pid du bruger
er et id genereret af programmet eller databasen (antager at du bruger
databasens indbyggede auto-nummerering). Sᅵ er dit input ikke fra
brugeren, og der er ingen risiko ved en almindelig query, og den indre
lᅵkke kan bruge $mysqli->query($query).
Der er andre mᅵder at omgᅵ problemet - dine data kan hentes med en join
- og jeg mener ogsᅵ der er mulighed for at store data, sᅵ der faktisk
kan arbejdes med 2 prepared statements.
Men det er nok lidt langhᅵret for dig, endnu... ;>)

Philip Nunnegaard

unread,
Jul 24, 2012, 1:59:59 AM7/24/12
to
Birger Sᅵrensen skrev:

> Du arbejder sᅵ med 2 forbindelser til databasen. Og det er vel ogsᅵ godt
> nok ;>)

Det slog mig ogsᅵ, og helt tilfredsstillende synes jeg ikke at det er,
men et gennembrud er det i det mindste for mig.

Pᅵ et tidspunkt ryger jeg op pᅵ 3 forbindelser. Senere i "yderlᅵkken"
henter jeg fᅵrst tilknyttede tag-id'er og ud fra den id henter jeg sᅵ
det ord der hᅵrer til tag-id'en (altsᅵ for at hente de tags der er
knyttet til indlᅵgget/artiklen). Samme sag med kategorier.

> Problemet er, at mysqli ikke kan arbejde med mere end een prepared
> statement, sᅵ det gᅵr galt nᅵr du bruger fetch() i begge lᅵkker.

Jeg forstᅵr det sᅵdan at man kun kan kᅵre ᅵn forespᅵrgsel pr.
forbindelse nᅵr man arbejder med prepared statements?

Man kan selvfᅵlgelig sige at i langt de fleste tilfᅵlde vil jeg kun
skulle basere ᅵn af lᅵkkerne pᅵ input fra brugeren, men sᅵ ryger jeg vel
alligevel op i 2 forbindelser: En med prepared statements plus en
"almindelig" gammeldags mysql-forbindelse.

En anden mᅵde jeg overvejede at lᅵse det pᅵ, fᅵr jeg kom pᅵ nuvᅵrende
lᅵsning, var at smide alle data fra yderlᅵkken ind i et almindeligt
array og sᅵ derefter lᅵbe de efterfᅵlgende tabeller igennem.

Mᅵske er det (af flere onder) bedre end at kᅵre med flere forbindelser
pᅵ en gang?

--
Philip

Anders Wegge Keller

unread,
Jul 24, 2012, 2:17:33 AM7/24/12
to
Philip Nunnegaard <nunne...@hitsurf.dk> writes:

> Birger Sørensen skrev:
>
> > Du arbejder så med 2 forbindelser til databasen. Og det er vel også godt
> > nok ;>)
>
> Det slog mig også, og helt tilfredsstillende synes jeg ikke at det er,
> men et gennembrud er det i det mindste for mig.

Du har ret i at det ikke er godt, og strengt taget er det heller ikke
nødvendigt.

Du kan omskrive dit SQL statement, så du kan nøjes med en forespørgsel:

SELECT pid, overskrift, tekst, dato, navn
FROM indlaeg LEFT JOIN brugere on indlaeg.pid = brugere.id
ORDER BY id DESC LIMIT 0,5

(Med forbehold for at der er en stavebøf et sted)

> På et tidspunkt ryger jeg op på 3 forbindelser. Senere i
> "yderløkken" henter jeg først tilknyttede tag-id'er og ud fra den id
> henter jeg så det ord der hører til tag-id'en (altså for at hente de
> tags der er knyttet til indlægget/artiklen). Samme sag med
> kategorier.

Det bliver et lidt mere langhåret query, men ellers er princippet det
samme som ovenfor. Som udgangspunkt vil jeg forvente at du får bedre
performance ud af at lade databasen gøre så meget arbejde for dig som
muligt.


>> Problemet er, at mysqli ikke kan arbejde med mere end een prepared
>> statement, så det går galt når du bruger fetch() i begge løkker.

> Jeg forstår det sådan at man kun kan køre én forespørgsel
> pr. forbindelse når man arbejder med prepared statements?

Som udgangspunkt, ja. Men du kan bruge mysqli::store_result() til at
gemme et tidligere resultat i en buffer. Jeg har ikke selv brugt den
metode, så jeg ved ikke hvordan det performer, eller hvor let det er
at gå til, men du kan da tage et kig på manualen.

<http://www.php.net/manual/en/mysqli.store-result.php>

> Man kan selvfølgelig sige at i langt de fleste tilfælde vil jeg kun
> skulle basere én af løkkerne på input fra brugeren, men så ryger jeg
> vel alligevel op i 2 forbindelser: En med prepared statements plus en
> "almindelig" gammeldags mysql-forbindelse.
>
> En anden måde jeg overvejede at løse det på, før jeg kom på nuværende
> løsning, var at smide alle data fra yderløkken ind i et almindeligt
> array og så derefter løbe de efterfølgende tabeller igennem.
>
> Måske er det (af flere onder) bedre end at køre med flere forbindelser
> på en gang?

Jeg ville prøve at lave nogle queries, der bruger JOIN og/eller
subselects til at få slutresultatet hevet ud af databasen i en omgang.

Stig Johansen

unread,
Jul 24, 2012, 2:34:19 AM7/24/12
to
Philip Nunnegaard wrote:

> Birger S�rensen skrev:
>
>> Du arbejder s� med 2 forbindelser til databasen. Og det er vel ogs� godt
>> nok ;>)
>
> Det slog mig ogs�, og helt tilfredsstillende synes jeg ikke at det er,
> men et gennembrud er det i det mindste for mig.
>
> P� et tidspunkt ryger jeg op p� 3 forbindelser. Senere i "yderl�kken"
> henter jeg f�rst tilknyttede tag-id'er og ud fra den id henter jeg s�
> det ord der h�rer til tag-id'en (alts� for at hente de tags der er
> knyttet til indl�gget/artiklen). Samme sag med kategorier.

Til den slags skal du bruge (INNER/LEFT OUTER) JOIN, som Birger skriver.

I den aktuelle 'sag' fra dit indl�g kunne du lave et statement som:
SELECT overskrift,tekst,dato
FROM indlaeg i
INNER JOIN brugere b ON b.id=i.pid
order by id desc limit 0,5

S� har du alle data i et enkelt rowset.

>> Problemet er, at mysqli ikke kan arbejde med mere end een prepared
>> statement, s� det g�r galt n�r du bruger fetch() i begge l�kker.
>
> Jeg forst�r det s�dan at man kun kan k�re �n foresp�rgsel pr.
> forbindelse n�r man arbejder med prepared statements?

Det har ikke rigtig noget med prepared eller ej, men om databasen kan
h�ndtere mere end 1 query pr. connection.

'Rigtige' databaser kan h�ndtere meget store antal, men f.eks. MS SQLServer
kan kun h�ntere 1.

MS SQLServer kloner dog yderligere forbindelser, s� omkostningen er ikke s�
stor igen.

> En anden m�de jeg overvejede at l�se det p�, f�r jeg kom p� nuv�rende
> l�sning, var at smide alle data fra yderl�kken ind i et almindeligt
> array og s� derefter l�be de efterf�lgende tabeller igennem.
>
> M�ske er det (af flere onder) bedre end at k�re med flere forbindelser
> p� en gang?

Nej den bedste l�sning er _altid_ at bruge JOIN's til den slags.
P� den m�de sker arbejdet i databaseserveren og ikke i klienten, med un�dig
trafik.

Og lige for en god ordens skyld:
En server og klient er et program, og ikke en maskine, s� i dette spil er
dit PHP program klient, og databasen er server.

Stig Johansen

unread,
Jul 26, 2012, 2:58:15 AM7/26/12
to
Anders Wegge Keller wrote:

> Som udgangspunkt vil jeg forvente at du får bedre
> performance ud af at lade databasen gøre så meget arbejde for dig som
> muligt.

Jeg kan se vore indlæg har krydset hinanden.

Indlægget her er blot for at bekræfte dine forventninger, fo man skal
_altid_ lade databasen lave arbejdet i det omfang det er muligt.

Dog skal man være lidt varsom med at lægge forretningslogik i databasen hvis
man samtidig har forretningslogik i programmet.

Den slags giver et vedligeholdelses helvede.

Taler af mere en 32 års erfaring med den slags ;-)

PS: Måske skal vi forklare Phillipo hvad forskeller er på INNER/LEFT
OUTER/RIGHT OUTER - JOIN er - når/hvis han kommer så langt.

Birger Sørensen

unread,
Jul 26, 2012, 4:10:16 AM7/26/12
to
Stig Johansen frembragte:
8X
> PS: Måske skal vi forklare Phillipo hvad forskeller er på INNER/LEFT
> OUTER/RIGHT OUTER - JOIN er - når/hvis han kommer så langt.

Det kunne da godt være, at der var nogen af os andre, der kunne have
glæde af en såden forklaring...?

Anders Wegge Keller

unread,
Jul 26, 2012, 4:47:02 AM7/26/12
to
Stig Johansen <wop...@gmail.com> writes:

> Anders Wegge Keller wrote:
>
> > Som udgangspunkt vil jeg forvente at du får bedre
> > performance ud af at lade databasen gøre så meget arbejde for dig som
> > muligt.
>
> Jeg kan se vore indlæg har krydset hinanden.

Ja, og heldigvis var vi enige om hvordan de to opslag skulle
kombineres.

> Indlægget her er blot for at bekræfte dine forventninger, fo man
> skal _altid_ lade databasen lave arbejdet i det omfang det er
> muligt.

Erfaringen har lært mig at der ikke går ret lang tid fra man
fremsætter et absolut udsagn onkring performance, før der opstår et
tilfælde der modbeviser udsagnet :/ Som udganspunkt er jeg ganske enig
med dig.

> Dog skal man være lidt varsom med at lægge forretningslogik i
> databasen hvis man samtidig har forretningslogik i programmet.

> Den slags giver et vedligeholdelses helvede.

> Taler af mere en 32 års erfaring med den slags ;-)

Jeg kender det fra den anden side: Forretningslogik i GUI. Det er
nøjagtig lige så slemt.

> PS: Måske skal vi forklare Phillipo hvad forskeller er på INNER/LEFT
> OUTER/RIGHT OUTER - JOIN er - når/hvis han kommer så langt.

Jeg tror du har serveretten der. Jeg kan ihvertfald ikke gøre det
bedre end denne (desværre engelske) wikipedia-artikel om emnet:
<http://en.wikipedia.org/wiki/Join_(SQL)>

Stig Johansen

unread,
Jul 26, 2012, 4:55:22 AM7/26/12
to
Birger Sørensen wrote:

> Stig Johansen frembragte:
> 8X
>> PS: Måske skal vi forklare Phillipo hvad forskeller er på INNER/LEFT
>> OUTER/RIGHT OUTER - JOIN er - når/hvis han kommer så langt.
>
> Det kunne da godt være, at der var nogen af os andre, der kunne have
> glæde af en såden forklaring...?

Selvfølgelig Birger, men den slags er typisk afhængig af den aktuelle
opgave.

Men jeg kan godt lave en kort 'forklaring':

Antag vi har to tabeller A og B.

A indeholder:
id
----
1
2
3

B indeholder
id
----
2
3
4

Nu er jeg gået et (lille) skridt videre i forhold til Philips indlæg, hvor
han har id og pid (så vidt jeg kan se).

Så går vi i gang med nogle forespørgsler.

1) Vi vil gerne have alle id'er fra tabel A - SELECT id FROM A.

Databaser indeholder ikke nogen 'naturlig' rækkefølge, så for at garantere
rækkefølgen skal man have en SORT BY, så
2) SELECT id FROM A ORDER BY id (evt desc for faldende orden).

Nu vil vi gerne sammenkoble de to tabeller og se
3) Hvad er fælles forekomster i de 2 tabeller - SELECT t1.id FROM A t1 INNER
JOIN B t2 ON t2.id=t1.id

Resultatet bliver:
id
-----
2
3

Her fortæller vi databasen hvilke felter der skal matche, id i begge
tilfælde.

Men når man bruger samme feltnavn skal databasen skelne mellem 'ambiguity',
så derfor bruges alias, så A -> t1 og B -> t2.

INNER JOIN giver med andre ord 'fællesmængeden' mellem de to tabeller.

Vi kan også stille et andet spørgsmål:
"Giv mig alle data fra A med tilhørende data fra B uanset om der er et
'tilhørsforhold'.

Det giver dette SQL:
4) SELECT t1.id AS f1, t2.id AS f2 FROM A t1 LEFT OUTER JOIN B t2 on
t2.id=t1.id

og resultatet:
f1 f2
---- -----
1 null
2 2
3 3

Denne SQL kan også bruges til at finde ikke sammenhængende entries i tabel B
ved at udvide den med en where klausul:

5) SELECT t1.id AS f1, t2.id AS f2 FROM A t1 LEFT OUTER JOIN B t2 on
t2.id=t1.id WHERE t2.id IS NULL, så får man kun første række i forhold til
ovenstående.

Så er der RIGHT OUTER JOIN, som jeg aldrig bruger, men det går ud på at se
på tabellerne fra højre mod venster i stedet for venstre mod højre.

I ovenstående eksempel skal man blot bytte om på A og B, og bruge RIGHT i
stedet for LEFT, og resultatet vil være det samme.

Phillip var lidt inde på 3 (eller flere) tabeller, og princippet er det
samme.

F.eks.
SELECT A.id,B.noget,C.noget_mere
FROM A t1
(INNER/LEFT OUTER) JOIN B t2 ON t1.noget=t2.noget
(INNER/LEFT OUTER) JOIN C t3 ON t2.noget=t3.noget
......
WHERE 'noget'
ORDER BY 'noget'
....
evt
GROUP BY 'noget' hvis man vil have aggrerede data.

I princippet er vi ovre i .database gruppen, men den er lige så død som alle
de andre, so what....

PS: vær opmærksom på de forskellige afvigelser fra standarden, herunder
Phillips brug af ' som _kun_ virker i mySQL, og vil skabe problemer ved
skift af database.

MS SQLServer indsætter 'automagisk' [ og ], ved brug af deres værktøjer til
SQL generering.

Fjerne alt hvad der ikke er standard, eller helst:
SKRIV DIT SQL SELV!

Philip Nunnegaard

unread,
Jul 26, 2012, 7:18:30 AM7/26/12
to
Stig Johansen skrev:

> Phillip var lidt inde på 3 (eller flere) tabeller, og princippet er det
> samme.

Jeps. På denne måde:
Der findes kun én forfatter (bruger/profil) til hver artikel, så her
ville jeg kunne klare den med en simpel sql-sætning der omfatter begge
tabeller.

Men der findes flere tags og ligeledes flere kategorier til hver artikel.

> PS: vær opmærksom på de forskellige afvigelser fra standarden, herunder
> Phillips brug af ' som _kun_ virker i mySQL, og vil skabe problemer ved
> skift af database.

Syntaksen til almindelig MySQL minder utroligt meget om syntaksen til en
Access-database. I begge tilfælde har jeg normalt brugt " til at
afgrænse sql-sætningen og ' inde i sætningen. Fx:

$sql = "insert into tabel (pid,navn) values (1,'Philip')";

I asp med acces skrev jeg "strSQL" i stedet for "$sql" og ingen
semikolon i slutningen. Det var eneste forskel.

Tak for din forklaring omkring de forskellige joins.

--
Philip

Philip Nunnegaard

unread,
Jul 26, 2012, 7:25:45 AM7/26/12
to
Anders Wegge Keller skrev:

> Jeg tror du har serveretten der. Jeg kan ihvertfald ikke gøre det
> bedre end denne (desværre engelske) wikipedia-artikel om emnet:
> <http://en.wikipedia.org/wiki/Join_(SQL)>

Tak for linket. Det er hermed bookmarket.

--
Philip

Anders Wegge Keller

unread,
Jul 26, 2012, 7:28:44 AM7/26/12
to
Philip Nunnegaard <nunne...@hitsurf.dk> writes:

> Stig Johansen skrev:
>
> > Phillip var lidt inde på 3 (eller flere) tabeller, og princippet er det
> > samme.
>
> Jeps. På denne måde:
> Der findes kun én forfatter (bruger/profil) til hver artikel, så her
> ville jeg kunne klare den med en simpel sql-sætning der omfatter begge
> tabeller.
>
> Men der findes flere tags og ligeledes flere kategorier til hver artikel.

Hvad er det du har brug for med hensyn til tags og kategorier?

- Finde alle artikler med en bestemt kombination af {tag, kategori}?
- Finde de nyeste artikler, og liste samtlige tags og kategorier?

Og kan du lige give et eksempel på tabelstruktur for hhv. tag og
kategori?

Stig Johansen

unread,
Jul 27, 2012, 3:17:40 AM7/27/12
to
Anders Wegge Keller wrote:

> Jeg kender det fra den anden side: Forretningslogik i GUI. Det er
> n�jagtig lige s� slemt.

Ja, det er ogs� grimt, og desv�rre ogs� brugt.

Det v�rste eksempel jeg nogensinde har set er Navision (Stat), som nok er
lavet n�sten _perfekt_ forkert, med forretningslogik i SP's, Triggers samit
i klienten (GUI'en).

> Jeg tror du har serveretten der. Jeg kan ihvertfald ikke g�re det
> bedre end denne (desv�rre engelske) wikipedia-artikel om emnet:
> <http://en.wikipedia.org/wiki/Join_(SQL)>

Den giver en rimelig god forklaring, men jeg er ikke tilfreds med man bruger
SELECT *... i de f�rste eksempler.

Man burde fort�lle det n�rmest er en d�dssynd (med mindre man vitterlig skal
bruge _alle_ elementerne).

L�ngere nede kommer man ind p� implicitte JOINS, som bla. Oracle kun
underst�ttede indtil 9i, men jeg vil foresl� man altid skriver eksplicitte
JOIN's s� optimizeren ikke skal bruge tid p� at 'g�tte' sig frem.

Men alle har vel deres holdninger - nogle tror det er bedre at lave 'korte'
programmer/SQL, bruger * fordi de er for dovne til at skrive et par
feltnavne osv.

Stig Johansen

unread,
Jul 27, 2012, 3:20:02 AM7/27/12
to
Anders Wegge Keller wrote:

> Hvad er det du har brug for med hensyn til tags og kategorier?
>
> - Finde alle artikler med en bestemt kombination af {tag, kategori}?
> - Finde de nyeste artikler, og liste samtlige tags og kategorier?
>
> Og kan du lige give et eksempel på tabelstruktur for hhv. tag og
> kategori?

Og helst også et eksempel på forentet resultat, som typisk giver en bedre
forståelse (for os andre).
0 new messages