Mysqli insert_id bij transaction met meerdere inserts
Code (php)
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
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;
?>
$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
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
Zet dan regel 56 met echo $conn->insert_id; eens na regel 24.
Inderdaad, dan doet hij het wel. Vreemd. Ik zou toch eerder verwachten dat de queries pas worden uitgevoerd bij regel 55...
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:
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?
Dit is vrij logisch? 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