Avatar billede hanibald Mester
28. november 2015 - 20:46 Der er 4 kommentarer og
1 løsning

foreach / 'distinct'

Jeg skal lave opslag i den ene side af en mange-til-mange tabel og kun bruge de unikke forekomster på den anden side.

Udtræk af alle forekomster på den anden side kører fint med nedenstående kode. Problemet er at 'distinct' (og måske andre parametre) ikke fungerer inde i en foreach-løkke.

Hvad kan gøres som alternativ til "select distinct dok_id ...."?


foreach($tags as $tag_id) 
{
$sql = "SELECT dok_id FROM doktags WHERE tag_id = ?";
        $query = $db_link->prepare($sql);
        $query->bind_param('i', $tag_id );
        $query->execute();
        $query->store_result();
        $query->bind_result($dok_id);
        $antal = $query->num_rows;
while($query->fetch()) {
echo "<br />".$dok_id;
}
Avatar billede Slater Ekspert
28. november 2015 - 21:45 #1
Generelt, hvis du er nødt til at køre et databasekald i en løkke, så har du gjort noget galt et sted. Enten i dit skemadesign eller i koden.

Her ser det umiddelbart ud til, at du kan køre en `WHERE tag_id IN (?)` for at få dem alle ud på en gang.

Hvis du skal bruge loops, så er det heller ikke meningen at du laver din prepared statement inde i løkken. Det giver ingen mening at forberede den hver gang.
Avatar billede hanibald Mester
29. november 2015 - 21:26 #2
Du har ret. Jeg havde overset IN()-parameteren.

Jeg har nu lavet min kode sådan:

        $tags= ($_POST['tags']);

        $sql = "SELECT dok_id FROM doktags WHERE tag_id in(?) ";
        $query = $db_link->prepare($sql);
        $query->bind_param('i', $tags );
        $query->execute();
        $query->store_result();
        $query->bind_result($dok_id);
        $antal = $query->num_rows;
    while($query->fetch()) {
    echo "<br />".$dok_id;
    }
        $query->close();


Jeg har tilpasset '$sql' og 'bind->param' og fjernet 'foreach'.

Jeg får til gengæld kun valideret mod første værdi i arrayen.
Skal der foretages tilpasning ved:
      $tags= ($_POST['tags']);
eller andet for at kunne validere mod alle værdier i arrayen???


PS: Du har ret vedr. forberedelse af statement. Jeg havde min aktuelle fokus andetsteds.
Avatar billede Slater Ekspert
30. november 2015 - 07:58 #3
Hvis $tags er en array af tal, så prøv
$query->bind_param('s', implode(',', $tags) );
Avatar billede hanibald Mester
07. december 2015 - 23:50 #4
Efter dit svar, samt megen googlen, gennemtrævling af stackoverflow, flere forsøg og bedre indsigt har jeg måttet erkende, at in() ikke (umiddelbat i hvert fald) kan anvendes. Jeg får i alle situationer advarslen:
"mysqli_stmt::bind_param(): Number of elements in type definition string doesn't match number of bind variables in ..."
- selvom jeg sætter 'iii' svarende til et aktuelle antal værdier i $tags.


Jeg har (indtil videre i det mindste) lagt projektet stille og er gået tilbage til:
----
$tags = array();
if (isset ($_POST['tags']) && $_POST['tags'] != "")
{
$tags = implode(',',($_POST['tags']));
$query = "select distinct dok_id from doktags where tag_id in($tags)";
$result = mysqli_query($db_link, $query) or die(mysqli_error($db_link));
while ($row = mysqli_fetch_assoc ($result))
{
echo $row['dok_id']. "<br />";  (midlertidig)
}
//        header ("Location: udtrek.php");
//        exit;
----

'Distinct' var den direkte årsag til, at jeg ikke ville anvende 'foreach'.

Forløbet har været lærerigt.

Må jeg bede om et point-svar.
Avatar billede hanibald Mester
07. januar 2016 - 15:35 #5
.
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

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