Mysqli insert_id bij transaction met meerdere inserts

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

25/02/2018 16:24:50
Quote Anchor link
Ik heb een mysql stransaction waarbij ik verschillende inserts pleeg. Slechts 1 insert heeft een auto_increment op het id. De overige zijn koppeltabellen of updates. Nu wil ik de id ophalen van de van de insert met auto_increment. Maar ik krijg steeds 0 terwijl de transaction verder wel goed uitgevoerd word. Hieronder de 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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<?php
$conn
= new mysqli(DB_HOST,DB_USER,DB_PASSWORD, DB_NAME);
        if ($conn === FALSE)
        {

            die("Connection failed: " . $conn->connect_error);
        }

        $return = FALSE;
        try
        {
            $conn->autocommit(FALSE);
            $sql = "
                    INSERT
                        facturen
                    SET
                        datum = NOW(),
                        organisatie = '"
. $oOrganisatie->id . "',
                        naam_organisatie = '"
. $oOrganisatie->organisatie . "',
                        contactpersoon = '"
. $oOrganisatie->contactpersoon . "';
                    "
;
            $res = $conn->query($sql);
            if ($res === FALSE)
            {

                throw new Exception('Wrong SQL: ' . $sql . ' Error: ' . $conn->error);
            }

            if (is_array($aEvenement))
            {

                foreach ($aEvenement as $oEvenement)
                {

                    $sql = "
                        UPDATE
                            evenementen
                        SET
                            gefactureerd = 1
                        WHERE
                            id = "
. $oEvenement->id . ";";
                    $res = $conn->query($sql);
                    if ($res === FALSE)
                    {

                        throw new Exception('Wrong SQL: ' . $sql . ' Error: ' . $conn->error);
                    }

                    $sql = "
                        INSERT
                            factuur_evenementen
                        SET
                            evenement = "
. $oEvenement->id . ",
                            factuur = LAST_INSERT_ID();
                        "
;
                    $res = $conn->query($sql);
                    if ($res === FALSE)
                    {

                        throw new Exception('Wrong SQL: ' . $sql . ' Error: ' . $conn->error);
                    }
                }
            }

            $conn->commit();
            echo $conn->insert_id;
            exit;
        }

        catch(Exception $e)
        {

            echo 'Transaction failed: ' . $e->getMessage();
              $conn->rollback();
        }

        finally
        {
            $conn->close();
        }

        return $return;
?>

Wat doe ik fout waardoor het mis gaat? Ik zit er al een paar uur blind op te staren.

Alle data is data die reeds in de database staat in andere tabellen. Er komt dus geen ongefilterde menselijke input aan te pas aan dit stuk van de code.

EDIT: extra info
Gewijzigd op 25/02/2018 16:28:39 door
 
PHP hulp

PHP hulp

25/04/2024 21:11:39
 
- SanThe -

- SanThe -

25/02/2018 16:34:29
Quote Anchor link
Waar komt LAST_INSERT_ID() vandaan?

Of zoek je dit?
Gewijzigd op 25/02/2018 16:37:04 door - SanThe -
 

25/02/2018 16:47:55
Quote Anchor link
-SanThe- bedankt voor de snelle reactie. mysqli->insert_id gebruik ik op regel 56 (echo $conn->insert_id;).
LAST_INSERT_ID() gebruik ik om in de transaction de id van de factuur query in de overige queries te kunnen gebruiken (INSERT
facturen
SET
datum = NOW(),
organisatie = '" . $oOrganisatie->id . "',
naam_organisatie = '" . $oOrganisatie->organisatie . "',
contactpersoon = '" . $oOrganisatie->contactpersoon . "';)
https://dev.mysql.com/doc/refman/5.7/en/information-functions.html#function_last-insert-id

echo $conn->insert_id; geeft steeds 0 als id ipv het id van de laast toegevoegde id in de tabel facturen
Gewijzigd op 25/02/2018 16:49:01 door
 
- SanThe -

- SanThe -

25/02/2018 17:44:01
Quote Anchor link
Zit de auto_increment in facturen?

Zet dan regel 56 met echo $conn->insert_id; eens na regel 24.
 

25/02/2018 20:29:37
Quote Anchor link
Inderdaad, dan doet hij het wel. Vreemd. Ik zou toch eerder verwachten dat de queries pas worden uitgevoerd bij regel 55...
 
Thomas van den Heuvel

Thomas van den Heuvel

25/02/2018 20:51:51
Quote Anchor link
Dit is vrij logisch? insert_id() retourneert het auto-increment id van de laatst uitgevoerde query. Een koppeltabel heeft doorgaans geen auto-increment id. Dit stond ook in de documentatie:
Quote:
... if the modified table does not have a column with the AUTO_INCREMENT attribute, this function will return zero.

Wanneer je een insert-id wilt bijhouden is de gangbare strategie dat je deze meteen na het uitvoeren van de query waar deze betrekking op heeft insert_id() aanroept en opslaat in een variabele.

De vraag is echter: waarvan wil je het AI-id bijhouden? Is dit van de factuur? Houd dan een $factuurId bij op regel 21. Dan gebruik je vervolgens $factuurId op regel 46 in plaats van LAST_INSERT_ID().

Weet ook niet of dat laatste nu goed gaat als je meerdere evenementen hebt? Heeft LAST_INSERT_ID() wel de goede waarde bij het invullen van de tweede en latere koppeltabelrijen? Want de query ervoor (eerste koppeltabelregel) had geen AI-kolom?

Ik zou even goed controleren of de juiste gegevens wel aan elkaar gehangen worden, het tussendoor opslaan van het AI-id kan hierbij helpen.

Wat mij ook het volgende doet afvragen: heeft de koppeltabel wel foreign keys ingesteld? De database zou toch moeten tegensputteren als je een foreign key met id 0 invoert? Welke database-engine gebruiken deze tabellen?
Gewijzigd op 25/02/2018 22:21:03 door Thomas van den Heuvel
 



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.