Data invoeren in meerdere/joined tabellen

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Mohamed nvt

Mohamed nvt

25/12/2016 21:41:37
Quote Anchor link
Hallo allemaal,

Via een form probeer ik data in te voeren in meerdere/joined tabellen.
Helaas gaat het niet goed, en ik krijg een vage foutmelding m.b.t. een Undefined variable. Deze twee variabelen heb ik eerder aangemaakt in het form gedeeld, nl;
$medicinetype_id
$supplier_id
Verder dan deze foutmelding krijg ik de foutmelding:

Error: Cannot add or update a child row: a foreign key constraint fails (`DB2681116`.`medicines_medicinestype`, CONSTRAINT `medicines_medicinestype_ibfk_2` FOREIGN KEY (`medicinetype_id`) REFERENCES `medicinestype` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)

En volgens mij klopt deze foutmelding, omdat het eerder genoemde variabelen mislukt en wordt er geen id gevonden in beide tabellen.

En verder vraag ik me af of mijn code correct is wat betreft syntaxis, logische stappen en veiligheid.
Ik hoop dat mijn verhaal duidelijk is en dat iemand mij wat feedback kan geven hoe ik het wel kan gaan oplossen.

Form code
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<form action="med_insert.php" method="post">
    <fieldset>
    
    <p><label for="medicinename"><b>Medicine Name:</b></label> <input type="text" name="medicinename" id="medicinename" value="<?php if (isset($trimmed['medicinename'])) echo $trimmed['medicinename']; ?>" /></p>
    
    <p><label for="productiondate"><b>Production Date:</b></label> <input type="text" name="productiondate" id="productiondate" value="<?php if (isset($trimmed['productiondate'])) echo $trimmed['productiondate']; ?>" /></p>

    <p><b><label for="expirationdate">Expiration Date:</b></label> <input type="text" name="expirationdate" id="expirationdate" value="<?php if (isset($trimmed['expirationdate'])) echo $trimmed['expirationdate']; ?>" /> </p>
    
    <p><b><label for="medicineprise">Medicine price:</b></label> <input type="text" name="medicineprise" id="medicineprise" value="<?php if (isset($trimmed['medicineprise'])) echo $trimmed['medicineprise']; ?>" /> </p>
    
    <p><label for="medicinetypename"><b>Select medicine type:</b></label>
    <select name="medicinetypename">
    <option value="">---Select---</option>
        <?php
        require_once (MYSQL);
        $query = "SELECT * from medicinestype";
        $result = mysqli_query($dbc,$query);
        if(!$result){
            die ("query failed" . mysqli_error($dbc));    
        }

        while ($row = mysqli_fetch_assoc($result)){
                $medicinetype_id = $row['id'];
                $medicinetypename = $row['medicinetypename'];
            echo "<option value='$medicinetype_id'>{$medicinetypename}</option>";
        }

        ?>

    </select></p>    
    <p><label for="suppliername"><b>Delivered by supplier:</b></label>
    <select name="suppliername">
        <option value="">---Select---</option>
        <?php

        $query2
= "SELECT * from suppliers";
        $result2 = mysqli_query($dbc,$query2);
        if(!$result2){
            die ("query failed" . mysqli_error($dbc));    
        }

        while ($row = mysqli_fetch_assoc($result2)){
                $supplier_id = $row['id'];
                $suppliername = $row['suppliername'];
            echo "<option value='$supplier_id'>{$suppliername}</option>";
        }

        ?>

    </select></p>
    
    
    </fieldset>
    
    <div align="center"><input type="submit" name="submit" value="Insert" /></div>

</form>


Zoals het boven eruit ziet, heeft het formulier een aantal invoer velden en twee dropdown-list. De gegevens van deze dropdown-list worden dmv een php script uit de db gehaald.

Code om in te voeren:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
<?php
if (!isset($_SESSION['user_id'])) {
    
    $url = BASE_URL . 'index.php'; // Define the URL.
    ob_end_clean(); // Delete the buffer.
    header("Location: $url");
    exit(); // Quit the script.
    
}else{
    
    echo "Welcome " . "{$_SESSION['firstname']}";
}


if ($_SERVER['REQUEST_METHOD'] == 'POST') { // Handle the form.

    // Need the database connection:

    require_once (MYSQL);
    
    // Trim all the incoming data:
    $trimmed = array_map('trim', $_POST);

    // Assume invalid values:
    $mn = $pd = $ed = $mp = $mtn = $sp = FALSE;
    
    // Check for a medicine name:
    if (preg_match ('/^[A-Z \'.-]{2,20}$/i', $trimmed['medicinename'])) {
        $mn = mysqli_real_escape_string ($dbc, $trimmed['medicinename']);
    }
else {
        echo '<p class="error">Please enter a medicine name!</p>';
    }


    // Check for a production date name:
    if (!empty($trimmed['productiondate'])) {
        $pd = mysqli_real_escape_string ($dbc, $trimmed['productiondate']);
    }
else {
        echo '<p class="error">Please enter a production date for this medicine!</p>';
    }

    
    // Check for a expiration date name:
    if (!empty($trimmed['expirationdate'])) {
        $ed = mysqli_real_escape_string ($dbc, $trimmed['expirationdate']);
    }
else {
        echo '<p class="error">Please enter an expiration date for this medicine!</p>';
    }

    // Check for a medicine price:
    /*
    if (preg_match ('/^[A-Z \'.-]{2,40}$/i', $trimmed['medicineprise'])) {
        $mp = mysqli_real_escape_string ($dbc, $trimmed['medicineprise']);
    } else {
        echo '<p class="error">Please enter an expiration date for this medicine!</p>';
    }*/

    
    if(!empty($trimmed['medicinetypename'])){
        $mtn = $trimmed['medicinetypename'];
        }
else {
            echo '<p class="error">Please select a medicinetype name for this medicine!</p>';
        }

    if(!empty($trimmed['suppliername'])){
        $sp = $trimmed['suppliername'];
        }
else {
            echo '<p class="error">Please select a medicine supplier for this medicine!</p>';
        }
    
        
    if ($mn && $pd && $ed && $mp && $mtn && $sp) { // If everything's OK...

            // Add the medicine to the database:

            $q = "INSERT INTO medicines
            (medicinename, productiondate, expirationdate,medicineregistration, medicineprice, userid)
            VALUES ('$mn','$pd', '$ed', NOW(), '$mp', '{$_SESSION['user_id']})'"
;
            $r = mysqli_query ($dbc, $q) or trigger_error("Query: $q\n<br />MySQL Error: " . mysqli_error($dbc));
            $medicine_id= mysqli_insert_id($dbc);
            $q2 = "INSERT INTO medicines_medicinestype
            (medicine_id,medicinetype_id)
            VALUES ('$medicine_id','$medicinetype_id')"
;
            $r2 = mysqli_query ($dbc, $q2) or trigger_error("Query: $q\n<br />MySQL Error: " . mysqli_error($dbc));
            $q3 = "INSERT INTO medicines_suppliers
            (medicine_id,supplier_id)
            VALUES ('$medicine_id','$supplier_id')"
;
            $r3 = mysqli_query ($dbc, $q3) or trigger_error("Query: $q\n<br />MySQL Error: " . mysqli_error($dbc));
            if (mysqli_affected_rows($dbc) == 1) { // If it ran OK.
                
                // Finish the page:

                echo '<h3>Thanks for adding medicines to the system!</h3>';
                include ('includes/footer.php'); // Include the HTML footer.
                exit(); // Stop the page.
                
            } else { // If it did not run OK.
                echo '<p class="error">There is no medicines saved to the system due to a technical error.
                We apologize for any inconvenience.</p>'
;
            }
            
        }
else { // If one of the data tests failed.
        echo '<p class="error">Please try again.</p>';
    }

}
// End of the main Submit conditional.
?>
Gewijzigd op 25/12/2016 21:44:05 door Mohamed nvt
 
PHP hulp

PHP hulp

25/11/2020 00:37:51
 
Frank Nietbelangrijk

Frank Nietbelangrijk

26/12/2016 00:11:56
Quote Anchor link
>> Deze twee variabelen heb ik eerder aangemaakt in het form

Dat klinkt mij vreemd in de oren. Je zou namelijk eerst je PHP programma logica moeten laten uitvoeren en daarna pas je pagina (met form) renderen.

Dus ongeveer in deze volgorde:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
// initialisatie van de variabelen zodat ze altijd bestaan
$name = '';

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    $name = $_POST['name'];
    // doe iets
}
?>

<html>
<body>
Hier mag je alleen nog een foreach lusje en echo's gebruiken om je variabelen weer te geven tussen de html.
Verder gebruik je hier geen PHP meer.
    <form action="" method="post">
        <input type="text" name="name" value="<?php echo $name; ?>">
        <button>Verzenden</button>
    </form>
</body>
</html>
Gewijzigd op 26/12/2016 00:17:25 door Frank Nietbelangrijk
 
Mohamed nvt

Mohamed nvt

27/12/2016 15:27:05
Quote Anchor link
Hallo Frank,

Bedankt voor je feedback.
Door jouw suggestie is het een deel van het probleem nu opgelost en het andere deel lukt het me helaas niet om het werkend te krijgen.
Overigens, jouw feedback vind ik wel logisch en toch heb ik de volgende vragen:

Het form pagina laadt toch als volgt:
1. initiële php code voor het form wordt niet uitgevoerd, omdat er nog niet is gedrukt op het submit knop.
1. gegevens worden ingevoerd in het formulier
2. aangemaakt variabelen gaan mee met de array post?
3. vervolgens roep ik deze variabelen die ik eerder heb aangemaakt, voordat er op de knop submit is gedrukt.


Om het andere deel van het probleem op te lossen, heb ik verschillende sites bezocht en hun suggesties opgevolgd, maar toe nu toe geen helaas succes.

De foutmelding is nog steeds hetzelfde. Vreemd genoeg binnen phpmyadmin lukt het me wel om om gegevens in te voeren in de tabellen: medicines_medicinestype & medicines_suppliers. Echter, met behulp van een php script krijg ik de foutmelding:

MySQL Error: Cannot add or update a child row: a foreign key constraint fails (`DB2681116`.`medicines_medicinestype`, CONSTRAINT `medicines_medicinestype_ibfk_2` FOREIGN KEY (`medicinetype_id`) REFERENCES `medicinestype` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)
Date/Time: 12-27-2016 00:58:31


MySQL Error: Cannot add or update a child row: a foreign key constraint fails (`DB2681116`.`medicines_suppliers`, CONSTRAINT `medicines_suppliers_ibfk_2` FOREIGN KEY (`supplier_id`) REFERENCES `suppliers` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)
Date/Time: 12-27-2016 00:58:31

Om dit probleem op te lossen heb ik de volgende stappen reeds uitgevoerd:
1. meicine tabel leeggemaakt, opdat het helemaal schoon is van welke waardes dan ook
2. medicines_medicinestype leeggemaakt, opdat er ontbrekende waardes zijn
3. medicines_suppliers tabel leeggemaakt, idem dito als vorige tabel.
4. huidge relaties tussen medicine en medicines_medicinestype aangemaakt met als optie cascade voor delete & update. Deze actie heb ik ook uitgevoerd voor de andere relevante tabellen.

jij/jullie nog een idee hoe ik dit toch tot een goede einde kan brengen?
 
Frank Nietbelangrijk

Frank Nietbelangrijk

27/12/2016 15:53:44
Quote Anchor link
Betreft het formulier:

In 99 van de 100 gevallen wil je dat een formulier telkens weer tevoorschijn komt TOTDAT er geen fouten meer ontdekt worden in de ingevulde gegevens en het formulier verwerkt kan worden. Het makkelijkste is dan dus om het formulier telkens naar dezelfde pagina terug te POSTen. Dat bereik je door simple het action attribuut leeg te laten:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
<form action="" method="post">

De pagina met het formulier kan nu in POST methode worden aangeroepen of gewoon in de GET methode.
Afhankelijk van deze methode kun je bepaalde acties verrichten
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
<?php
// acties die je hier plaatst gebeuren ALTIJD
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    // acties die je hier plaatst gebeuren als de pagina in de POST methode wordt aangeroepen
} else {
    // acties die je hier plaatst gebeuren als de pagina in de GET methode wordt aangeroepen
}
// acties die je hier plaatst gebeuren ALTIJD
?>


VARIABELEN
Variabelen kun je bovenin je programma aanmaken en een standaard waarde geven. We noemen dat initialiseren.
Daarna kun je de variabelen (afhankelijk van factoren) gewoon weer overschrijven en ze een andere waarde geven:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
<?php
// initialisatie van de variabelen zodat ze altijd bestaan
$name = '';

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    // overschrijf $name met een nieuwe waarde
    $name = $_POST['name'];
}


// VOORDEEL: No matter welke methode gebruikt is; $name bestaat ALTIJD!
?>


Vervolgens wil je als er geen fouten opgetreden zijn dat het formulier verwerkt wordt en de gebruiker doorgestuurd wordt naar een andere pagina
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
// initialisatie van de variabelen zodat ze altijd bestaan
$name = '';
$error_name = '';

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    // overschrijf $name met een nieuwe waarde
    $name = $_POST['name'];

    if(strlen($name) >= 2) {
        // doe iets dat nodig is om het formulier te verwerken zoals gegevens opslaan in de database of het sturen van een email
        header('Location: confirmation.php');
        exit;
    }
else {
        $error_name = 'U heeft geen naam opgegeven.'; // echo dit in je view
    }
}

?>


MySQL Error
Dit staat los van je formulier. Om je hiermee beter te kunnen helpen zou je even de indeling van de tabellen medicines_medicinestype_ibfk_2 en medicinestype kunnen posten. Je hebt in iedergeval een paar beperkingen toegevoegd met betrekking tot je tabellen. Ik ga er nog even naar kijken.

Toevoeging op 27/12/2016 16:09:38:

Waarschijnlijk moet de kolom medicinetype_id een BESTAAND id zijn in de medicinestype tabel.
Gewijzigd op 27/12/2016 16:06:14 door Frank Nietbelangrijk
 
Mohamed nvt

Mohamed nvt

27/12/2016 20:02:02
Quote Anchor link
Hallo Frank,

Ik heb nog eens na het probleem gekeken en merkte dat kolomtypes uit de originele tabel niet overeenkwamen met de reference tabel. Ik heb foreign key relatie verwijderd en de eigenschappen van de tabellen in de reference tabel aangepast, zodat deze precies overeenkomen met de kolomtypes uit de originele tabel. Helaas mocht dit niet baten. Ik krijg nog steeds dezelfde foutmelding wanneer ik via het form een medicijn wil invoeren gekoppeld aan een medicinetype en supplier, maar via de PHPMyAdmin werkt het wel wanneer ik een medicijn invoeren in de originele tabel en vervolgens de ids wil koppelen in de reference tabel.

Van mijn hostingprovider heb ik helaas geen toestemming om het commmando show create tabel uit te voeren en dus heb ik van elke relevante tabel een print screen gemaakt.
Hopelijk heb je dan nu alle info:

medicines tabel: http://dev.pc-on-rails.nl/user_registration/medicines.png
medicinestype tabel: http://dev.pc-on-rails.nl/user_registration/medicinestype.png
suppliers tabel: http://dev.pc-on-rails.nl/user_registration/suppliers.png
medicines_medicinestype tabel: http://dev.pc-on-rails.nl/user_registration/medicines_medicinestype.png
medicines_suppliers tabel: http://dev.pc-on-rails.nl/user_registration/medicines_suppliers.png
Gewijzigd op 27/12/2016 20:02:39 door Mohamed nvt
 
Frank Nietbelangrijk

Frank Nietbelangrijk

27/12/2016 20:42:56
Quote Anchor link
Ik begrijp dat je een many-to-many relatie wilt tussen verschillende medicijnen en leveranciers. Het zelfde geldt voor de medicijnen en de types-medicijnen.

Omdat beiden relaties hetzelfde zijn (alleen een andere naam) ga ik even van de eerste uit: medicijnen en leveranciers.

Een many to many relatie bestaat uit drie tabellen. In dit geval:
- medicijnen
- leveranciers
- medicijnen_leveranciers

de laatste is de koppeltabel zoals we die noemen.
De tabellen leveranciers en medicijnen zijn vrij normale tabellen. Ze moeten een auto-increment pimary-index hebben. Moeten is hier misschien een groot woord maar ga er maar even van uit.

Je medicijnen tabel kan er dan ongeveer zo uit zien:
- id (int11, auto-increment, primary-key)
- naam (varchar)
- ...

Hetzelfde geldt voor leveranciers.

De koppeltabel heeft twee kolommen:
- medicijn_id
- leverancier_id

Deze twee kolommen mogen alleen een waarde bevatten die je in de andere tabellen kunt terugvinden:
bijvoorbeeld:
de tabel medicijnen heeft alleen deze regel: 33 paracetamol. In de koppeltabel mag er bij medicijn_id alleen maar de waarde 33 gekozen worden daar dit het enigste id is in de tabel medicijnen.

Daarom voegen we twee beperkingen toe:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
ALTER TABLE `medicijnen_leveranciers`
  ADD CONSTRAINT `beperking1` FOREIGN KEY (`medicijn_id`) REFERENCES `medicijnen` (`id`),
  ADD CONSTRAINT `beperking2` FOREIGN KEY (`leverancier_id`) REFERENCES `leveranciers` (`id`);


Echter dit betekent wel dat we pas een medicijn aan een leverancier kunnen koppelen wanneer beiden reeds in de andere tabellen bestaan! om 1 NIEUW medicijn aan 1 NIEUWE leverancier te koppelen heb je dus DRIE queries nodig. en de derde query (die van de koppeltabel) moet dan ook als laatste.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
INSERT INTO `medicijnen` (`id`, `name`) VALUES (NULL, 'Paracetamol');
INSERT INTO `leveranciers` (`id`, `name`) VALUES (NULL, 'Bayer');
INSERT INTO `medicijnen_leveranciers` (`medicijn_id`, `leverancier_id`) VALUES (1, 1);


Die (1, 1) hier boven staan natuurlijk voor het juiste id van de zojuist aangemaakte records.
gebruik
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
<?php $newId = mysqli_insert_id($dbc); ?>
om het id van de laatste INSERT te verkrijgen.

Hier de dump van mijn voorbeeld. Je kunt die eens importeren om er naar te kijken.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
CREATE TABLE `leveranciers` (
  `id` int(11) NOT NULL,
  `name` varchar(50) COLLATE utf8_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;


CREATE TABLE `medicijnen` (
  `id` int(11) NOT NULL,
  `name` varchar(50) COLLATE utf8_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;


CREATE TABLE `medicijnen_leveranciers` (
  `medicijn_id` int(11) NOT NULL,
  `leverancier_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;


ALTER TABLE `leveranciers`
  ADD PRIMARY KEY (`id`);

ALTER TABLE `medicijnen`
  ADD PRIMARY KEY (`id`);

ALTER TABLE `medicijnen_leveranciers`
  ADD PRIMARY KEY (`medicijn_id`,`leverancier_id`),
  ADD KEY `medicijn_id` (`medicijn_id`),
  ADD KEY `leverancier_id` (`leverancier_id`);

ALTER TABLE `leveranciers`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

ALTER TABLE `medicijnen`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

ALTER TABLE `medicijnen_leveranciers`
  ADD CONSTRAINT `beperking1` FOREIGN KEY (`medicijn_id`) REFERENCES `medicijnen` (`id`),
  ADD CONSTRAINT `beperking2` FOREIGN KEY (`leverancier_id`) REFERENCES `leveranciers` (`id`);
Gewijzigd op 27/12/2016 20:54:04 door Frank Nietbelangrijk
 
Ger van Steenderen
Tutorial mod

Ger van Steenderen

27/12/2016 21:05:15
Quote Anchor link
Frank Nietbelangrijk op 27/12/2016 15:53:44:
....
Waarschijnlijk moet de kolom medicinetype_id een BESTAAND id zijn in de medicinestype tabel.

Dat klopt, anders zou het aanbrengen van een foreign key constraint weinig zin hebben.

@Mohammed
Ik zie dat je bij een mysql fout ook de query toont, volgens mij moet je daaraan kunnen zien dat bepaalde velden leeg zijn of niet goed doorkomen.
Zo te zien gebruik je variabelen in de query (bv $medicinetype_id) die nergens gedeclareerd worden.

Overigens gebruik geen ON UPDATE CASCADE voor FK's die refereren aan een AUTO_INCREMENT kolom, dit zijn door de DB gegenereerde waardes die horen niet door een gebruiker te worden aangepast.
Gewijzigd op 27/12/2016 21:16:22 door Ger van Steenderen
 
Mohamed nvt

Mohamed nvt

27/12/2016 21:12:07
Quote Anchor link
Hallo Frank,

Bedankt voor je snelle reactie.
Dus als ik je goed begrijp, moet het volgende gebeuren om een medicijn te kunnen koppelen aan een medicijntype en aan een medicijn leverancier:
1. medicijn invoeren in medicijn tabel
2. leverancier invoeren in leverancier tabel
3. in de koppel tabel het medicijn_id en het leverancier_id invoeren...


En in mijn geval gaat het dus anders:
1. medicijn invoeren in de medicijn tabel samen met userid "userid bestaat reeds en dit gaat ook goed. btw; er bestaat ook een fk-constrain tussen medicijn tabel en users"
2. uit de eerste dropdown-menu wordt een medicijntype geselecteerd "medicijntype bestaat dus al"
3. uit de tweede dropdown-menu wordt een leverancier geselecteerd "leverancier bestaat dus al"
4. Vervolgens wordt alle velden gecontroleerd en daarna worden er drie query's uitgevoerd:
. medicijn invoeren in de medicijn tabel samen met userid "tot nu toe gaat dit altijd goed"
. laatste inserted id van de zojuist ingevoerde medicijn wordt opgepakt en in een variabel gezet
. medicijn id + het id van de eerder geselecteerde medicijnetype worden ingevoerd in medicines_medicinestype "gaat niet goed en dus foutmelding mbt foreign key constrain"
. medicijn id + het id van de eerder geselecteerde leverancier worden ingevoerd in de medicines_suppliers tabel "gaat niet goed en dus foutmelding mbt foreign key constrain"

Mijn concrete vragen zijn dan:

1. hoe verklaar je dat tijdens het invoeren van een medicijn het wel lukt om het id van ingelogde gebruiker samen in te kunnen voeren in de medicijn tabel? user_id bestaat reeds en betreffende gebruiker is ook ingelogd, en er is een FK-constrain tussen medicijn tabel + users.
2. het lijkt me niet logisch/praktisch om elke keer wanneer ik een nieuw medicijn wil invoeren, ook medicijnetype invoeren en het leverancier. Omdat het niet logisch klinkt om een medicijnetype uit je hoofd te kennen en telkens de naam van leverancier in te voeren om maar een voorbeeld te noemen....hopelijk is mijn punt nu duidelijk?
3. Is er toch een manier om een medicijnetype en leverancier samen te kunnen invoeren wanneer er een nieuw medicijn wordt ingevoerd?



Toevoeging op 27/12/2016 21:54:16:

"Ger:
@Mohammed
Ik zie dat je bij een mysql fout ook de query toont, volgens mij moet je daaraan kunnen zien dat bepaalde velden leeg zijn of niet goed doorkomen.
Zo te zien gebruik je variabelen in de query (bv $medicinetype_id) die nergens gedeclareerd worden.

Hallo Ger van Steenderen,

Daar zeg je idd iets heel nuttig!
Ik heb dus nogmaals naar de output gekeken en het volgende viel me op:


Foutmelding:

dev/user_registration/med_insert.php' on line 92: Query: INSERT INTO medicines
(medicinename, productiondate, expirationdate,medicineregistration, medicineprice, userid)
VALUES ('Zanamivir Inhalaties','2011-01-01', '2011-12-31', NOW(), '3000', '3')
<br />MySQL Error: Cannot add or update a child row: a foreign key constraint fails (`DB2681116`.`medicines_suppliers`, CONSTRAINT `medicines_suppliers_ibfk_2` FOREIGN KEY (`supplier_id`) REFERENCES `suppliers` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)
Date/Time: 12-27-2016 23:36:10
========================================================
[medicine_id] => 19
[q2] => INSERT INTO medicines_medicinestype
(medicine_id,medicinetype_id)
VALUES ('19','')
[r2] =>
[q3] => INSERT INTO medicines_suppliers
(medicine_id,supplier_id)
VALUES ('19','')
=============================================
Hier boven kun je zien dat $medicinetype_id en $supplier_id geen waardes hebben. Tijdens het invoeren heeft de variabel geen waarde...
De FK-constrain faalt dan ook, omdat betreffende beide variabels geen waardes hebben en de FK-constrain er vanuit dat bijbehorende tabel uit de originele tabel niet bestaat...Eigenlijk heel logisch, en dit verklaart ook dat het binnen PHPMyAdmin het wel werkt, omdat bijbehorende id wel bekend zijn/gevonden worden....
Beide variabelen heb ik toch eerder aangemaakt en tijdens het laden van dropdown-menu wordt het id geladen....

Om toch achter de supplier_id en medicinetype_id te komen en te verwerken in de query, denk ik dan aan een subquery..Zit ik in de juiste richting?


"Ger:
Overigens gebruik geen ON UPDATE CASCADE voor FK's die refereren aan een AUTO_INCREMENT kolom, dit zijn door de DB gegenereerde waardes die horen niet door een gebruiker te worden aangepast.

Jawel, zie het laatste deel van de foutmelding, nl ....ON DELETE CASCADE ON UPDATE CASCADE)
 
Frank Nietbelangrijk

Frank Nietbelangrijk

27/12/2016 23:20:37
Quote Anchor link
>> Bedankt voor je snelle reactie. Dus ...
Klopt.

>> En in mijn geval gaat het dus anders: ...
Hier gaat het fout. Je moet een INSERT maar 1 keer uitvoeren voor een Leverancier of medicijn. Afhankelijk van de beperkingen in je database kan je een entity meerdere keren invoeren in je tabel maar dit is beslist niet de bedoeling en zal snel tot problemen leiden. Over het algemeen wordt er een bestaande entity uit een dropdown of met een autocomplete gekozen. Om een nieuwe entity toe te voegen zou je een button 'Toevoegen' kunnen maken waarna er een popup verschijnt waar je een entity kunt toevoegen. (een entity is bijvoorbeeld een leverancier of medicijn)

2. Om een medicijn in te kunnen voeren moet de gebruiker een medicijntype kiezen. Dit type moet bestaan en anders moet hij dit type toevoegen. zie punt 1.

>> Mijn concrete vragen zijn dan:
1. In de medicijnentabel staat een kolom user_id. Dit is een oneToMany relatie. Dit moet je niet verwarren met een manyToMany relatie. Bij een oneToMany heb je geen koppeltabel. In dit geval kan ieder medicijn maar 1 gebruiker hebben. Vandaar die 'One'. Echter Users kunnen meerder Medicijnen (ingevoerd) hebben, dus krijg je een oneToMany relatie. Bij medicijnen-leveranciers heb je een manyToMany relatie. Hier geldt het volgende:
- Medicijnen kunnen meerdere leveranciers hebben
- Leveranciers kunnen meerdere medicijnen hebben
MANY-TO-MANY dus.

Ik denk dat ik vraag twee en drie inmiddels wel heb beantwoord?





Toevoeging op 27/12/2016 23:49:09:

OneToMany
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
MEDICIJNEN
- id
- name
- user_id   <--- KOPPELING MET USERS !!!!

USERS
- id
- name
- email


ManyToMany
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
MEDICIJNEN
- id
- name

USERS
- id
- name
- email

USERS_MEDICIJNEN   <--- KOPPELTABEL !!!!
- user_id
- medicijn_id
Gewijzigd op 27/12/2016 23:42:29 door Frank Nietbelangrijk
 
Mohamed nvt

Mohamed nvt

31/12/2016 14:44:13
Quote Anchor link
Hallo Frank Nietbelangrijk,

Bedankt tot zover meedenken, en ik wil je graag mededelen dat het me gelukt hoe ik het precies wil :)

Het proces gaat als volgt:
1. gebruiker login
2. gebruiker voert een medicijn in en tegelijkertijd wordt ook zijn userd_id in de medicijn tabel ingevoerd. Dit, om straks de ingevoerde medicijn te kunnen koppelen aan deze gebruiker.
3. uit een dropdown-menu wordt een medicijntype en leverancier gekozen.

De volgende code heeft mij geholpen:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?php
$query
= "SELECT * from medicinestype";
        $result = mysqli_query($dbc,$query);
        if(!$result){
            die ("query failed" . mysqli_error($dbc));    
        }

        while ($row = mysqli_fetch_assoc($result)){
                $medicinetype_id = $row['id'];
                $medicinetypename = $row['medicinetypename'];
            echo "<option value='$medicinetype_id'>{$medicinetypename}</option>";
        }

        ?>

    </select></p>    
    <p><label for="suppliername"><b>Delivered by supplier:</b></label>
    <select name="suppliername">
        <option value="">---Select---</option>
        <?php

        $query2
= "SELECT * from suppliers where userid= '{$_SESSION['user_id']}'";
        $result2 = mysqli_query($dbc,$query2);
        if(!$result2){
            die ("query failed" . mysqli_error($dbc));    
        }

        while ($row = mysqli_fetch_assoc($result2)){
                $supplier_id = $row['id'];
                $suppliername = $row['suppliername'];
            echo "<option value='$supplier_id'>{$suppliername}</option>";
        }

        ?>

    </select></p>

?>


Omdat ik hierboven zowel medicinetype_id als supplier_id heb opgenomen voor de option value. Heb ik later tijdens het controleren van de post array het volgende ook opgevraagd:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<?php
//creating veriables for medicinetype_id and supplier_id
    $medicinetype_id =$_POST['medicinetypename'] ;
    $supplier_id = $_POST['suppliername'];
?>

Deze twee variabelen gebruik later tijdens de insert statements en het doet precies wat ik nl wil :)

Nogmaals bedankt voor het meedenken.
 
Frank Nietbelangrijk

Frank Nietbelangrijk

31/12/2016 14:52:55
Quote Anchor link
Fijn dat het gelukt is Mohamed.
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.