Avatar billede mr_bula Nybegynder
15. november 2006 - 13:51 Der er 36 kommentarer og
1 løsning

Sammenkæde tilbehør og produkt

Databasen: Jeg har blandtandet to tabeller tilbehor og produkt i min database. Imellem dem har jeg en relation som indeholder de to tabellers primær nøgler: t_id og p_id for at kunne sammenkæde tilbehøret til de relevante produktet.

Mit problem er så at jeg skal bruge en side hvor man kan tilføje tilbehør til et produkt og/eller tilføje et produkt til noget tilbehør.

Min ide var noget i stil a la at man skal gå ind på en side (vis_produkt.php?id=1) hvor så databasen henter alt tilbehør og man så kan klikke/markere det tilbehør der passer på den model man er gået ind på.
I databasen skal det skrives sådan her:

p_id | t_id
1    | 12
1    | 27
1    | 30

Håber I forstår mit spg, og kan hjælpe
Avatar billede coderdk Praktikant
15. november 2006 - 14:39 #1
Jeg antager at din tabel der binder tilbehor og produkter sammen hedder produkt_tilbehor. Dette er helt utestet, jeg har antaget feltnavne forskellige steder ;)

Tilbehør til produkt:

<?php

    $pid = $_GET['pid'];
    // Hent lidt info ud om produktet fra mysql
   
    $sql = "SELECT t.*, COALESCE(pt.p_id,0) AS pid FROM tilbehor AS t LEFT OUTER JOIN produkt_tilbehor AS pt ON t.t_id = pt.t_id WHERE pt.p_id = $pid";
    $qh = mysql_query( $sql ) or die( mysql_error() );
    $tilbehor = array();
    while ( $row = mysql_fetch_assoc( $qh ) )
    {
        $tilbehor[] = $row;
    }

?>
<form method="post" action="gem_produkt_tilbehor.php">
  <input type="hidden" name="pid" value="<? echo $_GET['pid'] ?>">
  Skriv lidt info om produktet ud her...<br>
  <select name="tid[]" multiple="multiple" rows="5">
<?

    foreach ( $tilbehor as $row )
    {
        echo "<option value=\"$row[t_id]\"";
        if ( $row['pid'] != 0 )
        {
            echo " selected=\"selected\"";
        }
        echo ">$row[tilbehorsnavn]</option>";
    }

?>
    </select>
    * Hold shift nede mens du vælger tilbehør<br>
    <input type="submit" name="sbmit" value="Gem">
</form>


og så gem_produkt_tilbehor.php:

<?php

    if ( $_SERVER['REQUEST_METHOD'] == 'POST' )
    {
        if ( count( $_POST['tid'] ) == 0 )
        {
            $sql = "DELETE FROM produkt_tilbehor WHERE p_id = " . $_POST['pid'];
            mysql_query( $sql ) or die( mysql_error() );
        }
        else
        {
            foreach ( $_POST['tid'] as $id )
            {
                $sql = "REPLACE INTO produkt_tilbehor (p_id, t_id) VALUES (" . $_POST['pid'] . "," . $id . ")";
                mysql_query( $sql ) or die( mysql_error() );
            }
        }
    }
   
    header( "location: produktliste.php" );

?>

Du kan bruge samme princip den modsatte vej, altså fra tilbehør til produkt...
Avatar billede coderdk Praktikant
15. november 2006 - 14:40 #2
$sql = "SELECT t.*, COALESCE(pt.p_id,0) AS pid FROM tilbehor AS t LEFT OUTER JOIN produkt_tilbehor AS pt ON t.t_id = pt.t_id WHERE pt.p_id = $pid";

skal muligvis være:

$sql = "SELECT t.*, COALESCE(pt.p_id,0) AS pid FROM tilbehor AS t LEFT OUTER JOIN produkt_tilbehor AS pt ON t.t_id = pt.t_id AND pt.p_id = $pid";

intet af det er testet
Avatar billede mr_bula Nybegynder
15. november 2006 - 18:25 #3
Jeg forstår ikke helt din start ($sql = "SELECT t.*, COALESCE(pt.p_id,0) ...) hvor kommer t. fra ....

Havde bare tænkt mig at jeg ville indlæse alle produkter fra tilbehør, derefter skal man så kunne vælge X antal tilbehør som passer til det produkt man har åbnet, og når man er færdig skal man så klikke på ok, og der skal kaldes op til tabellen "har", som har to attributer, t_id og p_id.

Når tilbehøret indlæses skal den tjekke om der allerede er tilknyttet noget tilbehør til produktet, og disse skal være markeret
Avatar billede coderdk Praktikant
15. november 2006 - 21:11 #4
t er et alias for tabellen tilbehor:

FROM tilebehor AS t

Så kan du tilgå felter i tilbehor som t.feltnavn - nyttigt når du skal lave joins :)

Prøv min kode, den gør det som jeg tror du vil - Den henter alt tilbehør og markerer det der findes i forvejen, og så kan du trykke CTRL eller SHIFT ned mens du vælger flere (som alm. listboxe i andre windowsapps)
Avatar billede mr_bula Nybegynder
16. november 2006 - 14:21 #5
Ok, men har stadig lidt problemer... har ændret variablerne til mine (det er ikke produkt mere men model, så har ændre alle p'er til m'er)..
Men jeg får en fejl: Unknown column 'mt.model_id' in 'field list'

Her er koden:
<?php
include_once("inc/session.php");
require_once("inc/connection_inc.php");
?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test</title>
</head>
<body>
<?php
    $conn = connection();
    $mid = $_GET['id'];
    $sql = "SELECT t.*, COALESCE(mt.model_id,0) AS model_id FROM tilbehor AS t LEFT OUTER JOIN har AS pt ON t.tilbehor_id = mt.tilbehor_id WHERE mt.model_id = $mid";
    $qh = mysql_query( $sql ) or die( mysql_error() );
    $tilbehor = array();
    while ( $row = mysql_fetch_assoc( $qh ) )
    {
        $tilbehor[] = $row;
    }
?>
<form method="post" action="gem_produkt_tilbehor.php">
  <input type="hidden" name="model_id" value="<? echo $_GET['id'] ?>">
  Skriv lidt info om produktet ud her...<br>
  <select name="tid[]" multiple="multiple" rows="5">
<?
    foreach ( $tilbehor as $row )
    {
        echo "<option value=\"$row[t_id]\"";
        if ( $row['model_id'] != 0 )
        {
            echo " selected=\"selected\"";
        }
        echo ">$row[tilbehorsnavn]</option>";
    }
?>
    </select>
    * Hold shift nede mens du vælger tilbehør<br>
    <input type="submit" name="sbmit" value="Gem">
</form>
og så gem_produkt_tilbehor.php:
<?php
    if ( $_SERVER['REQUEST_METHOD'] == 'POST' )
    {
        if ( count( $_POST['tid'] ) == 0 )
        {
            $sql = "DELETE FROM har WHERE model_id = " . $_POST['model_id'];
            mysql_query( $sql ) or die( mysql_error() );
        }
        else
        {
            foreach ( $_POST['tid'] as $id )
            {
                $sql = "REPLACE INTO har (model_id, tilbehor_id) VALUES (" . $_POST['model_id'] . "," . $id . ")";
                mysql_query( $sql ) or die( mysql_error() );
            }
        }
    }
 
    header( "location: produktliste.php" );
?>
</body>
</html>
Avatar billede coderdk Praktikant
16. november 2006 - 16:34 #6
Ændr "har AS pt" til "har AS mt"
Avatar billede mr_bula Nybegynder
16. november 2006 - 17:12 #7
Jep det var der fejlen var, men man kan jo ikke vælge tilbehør der passer til modellen med $_GET['id'].

Er det meningen at du vil have den til at gå direkte hen til produktliste.php?
Avatar billede coderdk Praktikant
16. november 2006 - 17:42 #8
nej den kode jeg prøvede at demonstrere var til at vise én produkt, hvor man så fik en select-liste hvor den der passer til er markerede, og hvor du kan markere flere for også at tilknytte dem...
Avatar billede mr_bula Nybegynder
16. november 2006 - 17:47 #9
Super det er også meningen, men den kode jeg postede går direkte til produktliste.php?
Avatar billede coderdk Praktikant
16. november 2006 - 17:50 #10
Du har postet indholdet til to separate filer... De skal adskilles der hvor der står "og så gem_produkt_tilbehor.php" ;)
Avatar billede mr_bula Nybegynder
17. november 2006 - 19:36 #11
Ja beklager, har ikke lige været tip top, du har endda skåret det ud i pap...

Men nu hvor jeg er på rette spor igen, så viser den kun det tilbehør som allerede er knyttet til modellen ellers er den blank hvis der ikke er knyttet noget til... Vil jo gerne have hele listen ud, og så skal tilbehøret som allerede er knyttet til være markeret
Avatar billede coderdk Praktikant
17. november 2006 - 20:28 #12
Prøv lige at lave:

$sql = "SELECT t.*, COALESCE(pt.p_id,0) AS pid FROM tilbehor AS t LEFT OUTER JOIN produkt_tilbehor AS pt ON t.t_id = pt.t_id AND pt.p_id = $pid";

om til:

$sql = "SELECT t.*, COALESCE(pt.p_id,0) AS pid FROM tilbehor AS t LEFT OUTER JOIN produkt_tilbehor AS pt ON t.t_id = pt.t_id";
Avatar billede b_ Nybegynder
17. november 2006 - 20:52 #13
Jep så spiller den del. Men har en syntaks fejl i gem_produkt_tilbehor delen:

<?php
include_once("inc/session.php");
require_once("inc/connection_inc.php");
$conn = connection();

    if ( $_SERVER['REQUEST_METHOD'] == 'POST' )
    {
        if ( count( $_POST['tid'] ) == 0 )
        {
            $sql = "DELETE FROM har WHERE model_id = " . $_POST['model_id'];
            mysql_query( $sql ) or die( mysql_error() );
        }
        else
        {
            foreach ( $_POST['tid'] as $id )
            {
                $sql = "REPLACE INTO har (model_id, tilbehor_id) VALUES (" . $_POST['model_id'] . "," . $id . ")";
                mysql_query( $sql ) or die( mysql_error() );
            }
        }
    }
 
    header( "location: produktliste.php" );

?>

Kan du finde den? Og mange tak fordi du gider at hjælpe...
Avatar billede coderdk Praktikant
17. november 2006 - 22:00 #14
b_ = mr_bula? Du må kun have én bruger ;)

Det ville hjælpe hvis du fortalte hvad syntaksfejlen var :P
Avatar billede mr_bula Nybegynder
17. november 2006 - 22:46 #15
Haha... flot, det er med min storebrors profil jeg har svaret. Han må åbenbart have være på i mellemtiden.

Får denne fejl:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 1
Avatar billede coderdk Praktikant
17. november 2006 - 22:53 #16
Prøv lige at erstatte:

<?php
include_once("inc/session.php");
require_once("inc/connection_inc.php");
$conn = connection();

    if ( $_SERVER['REQUEST_METHOD'] == 'POST' )
    {
        if ( count( $_POST['tid'] ) == 0 )
        {
            $sql = "DELETE FROM har WHERE model_id = " . $_POST['model_id'];
            mysql_query( $sql ) or die( mysql_error() );
        }
        else
        {
            foreach ( $_POST['tid'] as $id )
            {
                $sql = "REPLACE INTO har (model_id, tilbehor_id) VALUES (" . $_POST['model_id'] . "," . $id . ")";
                mysql_query( $sql ) or die( mysql_error() );
            }
        }
    }

    header( "location: produktliste.php" );

?>

med:

<?php
include_once("inc/session.php");
require_once("inc/connection_inc.php");
$conn = connection();

    if ( $_SERVER['REQUEST_METHOD'] == 'POST' )
    {
        $sql = "DELETE FROM har WHERE model_id = " . $_POST['model_id'];
        echo $sql;
        mysql_query( $sql ) or die( mysql_error() );
        foreach ( $_POST['tid'] as $id )
        {
          $sql = "REPLACE INTO har (model_id, tilbehor_id) VALUES (" . $_POST['model_id'] . "," . $id . ")";
          echo $sql;
          mysql_query( $sql ) or die( mysql_error() );
        }
    }

    header( "location: produktliste.php" );

?>

og se hvad den skriver...
Avatar billede mr_bula Nybegynder
17. november 2006 - 23:01 #17
Det er hos $id(tid) den er galt, den kommer ikke med nogen værdi...

DELETE FROM har WHERE model_id = 1 REPLACE INTO har (model_id, tilbehor_id) VALUES (1,)You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 1
Avatar billede coderdk Praktikant
17. november 2006 - 23:14 #18
Før:

foreach ( $_POST['tid'] as $id )

sæt denne ind og lad os se:

echo "<pre>"; var_dump( $_POST['tid'] ); echo "</pre>";
Avatar billede coderdk Praktikant
17. november 2006 - 23:14 #19
Eller:

echo "<pre>"; var_dump( $_POST ); echo "</pre>";

Så kan vi se alt hvad der bliver POST'et...
Avatar billede mr_bula Nybegynder
18. november 2006 - 01:45 #20
Outputtet:

array(3) {
  ["model_id"]=>
  string(1) "1"
  ["tid"]=>
  array(2) {
    [0]=>
    string(0) ""
    [1]=>
    string(0) ""
  }
  ["sbmit"]=>
  string(3) "Gem"
}
Avatar billede coderdk Praktikant
18. november 2006 - 05:34 #21
echo "<option value=\"$row[t_id]\"";

skal være:

echo "<option value=\"$row[tilbehor_id]\"";
Avatar billede mr_bula Nybegynder
18. november 2006 - 13:22 #22
Okay, den burde jeg selv havde set, men det spiller...

Tak for hjælpen, og din tålmodighed.

En sidste ting, vil du forklare denne: $sql = "SELECT t.*, COALESCE(mt.model_id,0) AS model_id FROM tilbehor AS t LEFT OUTER JOIN har AS pt ON t.tilbehor_id = mt.tilbehor_id WHERE mt.model_id = $mid";

Kender fx ikke COALESCE
Avatar billede mr_bula Nybegynder
18. november 2006 - 13:43 #23
okay det spiller alligevel ikke helt... Fx hvis jeg nu går ind på en model med et andet id(2), er tilbehøret fra det første id markeret selvom det andet id ikke har noget tilbehør tilknyttet, og ligeledes, hvis jeg tilknytter noget af det samme tilbehør til det id 2 som det id 1 også har kommer der "duplicates", og alt tilbehør der bare er tilknyttet et eller andet id bliver vist
Avatar billede coderdk Praktikant
18. november 2006 - 15:16 #24
Hmm prøv at ændre:

if ( $row['model_id'] != 0 )

til:

if ( $row['model_id'] == $mid )


COALESCE vælger den først i en liste som IKKE er NULL ;)

I vores tilfælde, hvor vi laver et LEFT OUTER JOIN, kan mt.model_id godt være NULL, derfor selecter jeg den med COALESCE, så hvis den er NULL returnerer den i stedet 0 :)

SELECT COALESCE(NULL,NULL,1);

returnerer 1 :)
Avatar billede mr_bula Nybegynder
18. november 2006 - 15:27 #25
Det løste problemet med selected, men der er stadig duplicates...

Altså vi siger at model 1 har tilbehor 1 og 2, og model 2 har tilbehor 2 og 3,

Så viser selectlisten med tilbehor
1
2
2
3

Så tilbehor bliver vist to gange. Hvis der nu er 10 modeller hvor et stykke tilbehor passer til vil de blive vist 10 gange
Avatar billede coderdk Praktikant
18. november 2006 - 16:05 #26
Gah, prøv at lave:

    foreach ( $tilbehor as $row )
    {
        echo "<option value=\"$row[t_id]\"";
        if ( $row['model_id'] != 0 )
        {
            echo " selected=\"selected\"";
        }
        echo ">$row[tilbehorsnavn]</option>";
    }


om til:

    $ids = array();
    foreach ( $tilbehor as $row )
    {
        if ( !in_array( $row['t_id'], $ids ) )
        {
            $ids[] = $row['t_id'];
            echo "<option value=\"$row[t_id]\"";
            if ( $row['model_id'] == $mid )
            {
                echo " selected=\"selected\"";
            }
            echo ">$row[tilbehorsnavn]</option>";
        }
    }

Hvis den så mangler noget tilbehør der burde være selected så lav:

$sql = "SELECT t.*, COALESCE(mt.model_id,0) AS model_id FROM tilbehor AS t LEFT OUTER JOIN har AS pt ON t.tilbehor_id = mt.tilbehor_id WHERE mt.model_id = $mid";

om til:

$sql = "SELECT t.*, COALESCE(mt.model_id,0) AS model_id FROM tilbehor AS t LEFT OUTER JOIN har AS pt ON t.tilbehor_id = mt.tilbehor_id WHERE mt.model_id = $mid ORDER BY model_id DESC";
Avatar billede mr_bula Nybegynder
18. november 2006 - 16:20 #27
Den første gør det næsten, men her selecter den kun tilbehør til en model dvs. hvis model 1 har tilbehor 1 kan tilbehor 1 ikke være selected ved andre modeller.

Anden del giver :Unknown column 'mt.model_id' in 'field list'
Avatar billede mr_bula Nybegynder
18. november 2006 - 16:26 #28
Okay det fatter jeg ikke hvorfor kender den lige pludselig ikke mt.model_id mere
Avatar billede mr_bula Nybegynder
18. november 2006 - 16:35 #29
har løst mt.model_id
Avatar billede mr_bula Nybegynder
18. november 2006 - 16:37 #30
men nu viser den kun de markerede
Avatar billede coderdk Praktikant
18. november 2006 - 17:26 #31
LEFT OUTER JOIN har AS pt

skal være

LEFT OUTER JOIN har AS mt
Avatar billede mr_bula Nybegynder
18. november 2006 - 17:50 #32
18/11-2006 16:35:19: har løst mt.model_id ;)

Men den viser kun de markerede, så hvis en model ikke allerede har nogle tilnyttet er tabellen tom
Avatar billede coderdk Praktikant
18. november 2006 - 19:01 #33
Ok, post lige den kode du har nu :)
Avatar billede coderdk Praktikant
18. november 2006 - 19:29 #34
Ok jeg tror jeg har den:

$sql = "SELECT t.*, COALESCE(mt.model_id,0) AS mid FROM tilbehor AS t LEFT OUTER JOIN har AS mt ON t.tilbehor_id = mt.tilbehor_id AND mt.model_id = $mid";

Denne:

    $ids = array();
    foreach ( $tilbehor as $row )
    {
        if ( !in_array( $row['t_id'], $ids ) )
        {
            $ids[] = $row['t_id'];
            echo "<option value=\"$row[t_id]\"";
            if ( $row['model_id'] == $mid )
            {
                echo " selected=\"selected\"";
            }
            echo ">$row[tilbehorsnavn]</option>";
        }
    }

Laves om til:

    foreach ( $tilbehor as $row )
    {
        $ids[] = $row['t_id'];
        echo "<option value=\"$row[t_id]\"";
        if ( $row['mid'] == $mid )
        {
            echo " selected=\"selected\"";
        }
        echo ">$row[tilbehorsnavn]</option>";
    }

Det burde virke - Jeg har lige testet noget lignende...
Avatar billede mr_bula Nybegynder
19. november 2006 - 13:39 #35
Ja selvfølelig virker det... Du er min helt ;)
Avatar billede coderdk Praktikant
19. november 2006 - 13:46 #36
Det var godt :)
Avatar billede mr_bula Nybegynder
21. november 2006 - 15:41 #37
Fortsættelse følger: http://www.eksperten.dk/spm/746216 ;)
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
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

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