Hoe kan ik een SELECT query gebruiken in een transactie en de data ophalen van de laatste insert
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?PHP
$conn->autocommit(FALSE);
$conn->multi_query('
INSERT INTO orders
(
producten
)
VALUES
(
"bla"
)');
$conn->multi_query('
UPDATE orders SET order_id = CONCAT(account_id, ".", id)
WHERE id = LAST_INSERT_ID()');
$conn->commit();
?>
$conn->autocommit(FALSE);
$conn->multi_query('
INSERT INTO orders
(
producten
)
VALUES
(
"bla"
)');
$conn->multi_query('
UPDATE orders SET order_id = CONCAT(account_id, ".", id)
WHERE id = LAST_INSERT_ID()');
$conn->commit();
?>
Nu wil ik in diezelfde transactie de gegevens ophalen uit de orders tabel met het last inserted id.
Met deze query:
Totaal dus op deze manier:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?PHP
$conn->autocommit(FALSE);
$conn->multi_query('
INSERT INTO orders
(
producten
)
VALUES
(
"bla"
)');
$conn->multi_query('
UPDATE orders SET order_id = CONCAT(account_id, ".", id)
WHERE id = LAST_INSERT_ID()');
$conn->multi_query('
SELECT * FROM orders WHERE id = LAST_INSERT_ID()');
$conn->commit();
?>
$conn->autocommit(FALSE);
$conn->multi_query('
INSERT INTO orders
(
producten
)
VALUES
(
"bla"
)');
$conn->multi_query('
UPDATE orders SET order_id = CONCAT(account_id, ".", id)
WHERE id = LAST_INSERT_ID()');
$conn->multi_query('
SELECT * FROM orders WHERE id = LAST_INSERT_ID()');
$conn->commit();
?>
Ik krijg op deze manier alleen de foutmelding:
Code (php)
1
There was an error running the query [Commands out of sync; you can't run this command now]
Hoe komt dit?
Gewijzigd op 04/02/2021 15:57:18 door Snelle Jaap
?
Dan moet je toch eerst het vorige SQL statement handmatig committen voordat je last_insert_id() kunt gebruiken?
Waarom doe je Dan moet je toch eerst het vorige SQL statement handmatig committen voordat je last_insert_id() kunt gebruiken?
Ad Fundum op 04/02/2021 16:16:10:
Omdat ik een transactie wil uitvoeren en ik las dat je dat met mysqli op deze manier doet.
"Dan moet je toch eerst het vorige SQL statement handmatig committen voordat je last_insert_id() kunt gebruiken?"
Blijkbaar hoeft dat niet want de update query pakt het juiste id bij LAST_INSERT_ID()
Gewijzigd op 04/02/2021 16:20:19 door Snelle Jaap
danwel in PHP een functie aanroepen om die 2 samen te voegen.
Dat zou al kunnen met
waarbij jouw object $order dan een functie kent
ja: het is mogelijk om direct bij de insert je afgeleide data ook in je tabel te krijgen.
maar soms komt dat met een hoop extra werk.
Je bent nu al een dag bezig hiermee, terwijl de recht-toe-recht-aan oplossing heel simpel te maken is.
En daarbij ook flexibel blijft voor het geval je ooit bedenkt dat in het ordernummer dat je toont ook nog het jaartal moet staan of dat je in plaats van de punt een streepje wilt hebben in je weergave.
Toevoeging op 04/02/2021 17:28:16:
en wat betreft je transactie: probeer anders te committen voor je de select query uitvoert (waarbij je eigenlijk vooraf al wist wat daar in kwam te staan, want dat zet je net in de 2 query's ervoor in je database
"en wat betreft je transactie: probeer anders te committen voor je de select query uitvoert (waarbij je eigenlijk vooraf al wist wat daar in kwam te staan, want dat zet je net in de 2 query's ervoor in je database"
Maar wat als twee mensen tegelijkertijd een order erin schieten, en dit script moet het last inserted id ophalen, kan dat dat geen potentiële problemen opleveren wanneer die select query niet ook in de transactie staat?
https://dev.mysql.com/doc/c-api/8.0/en/getting-unique-id.html
For LAST_INSERT_ID(), the most recently generated ID is maintained in the server on a per-connection basis. It is not changed by another client. It is not even changed if you update another AUTO_INCREMENT column with a nonmagic value (that is, a value that is not NULL and not 0). Using LAST_INSERT_ID() and AUTO_INCREMENT columns simultaneously from multiple clients is perfectly valid. Each client will receive the last inserted ID for the last statement that client executed.
Gewijzigd op 05/02/2021 15:41:43 door Ivo P
Ivo P op 05/02/2021 15:40:35:
LAST_INSERT_ID gaat om de laatste insert die jouw verbinding heeft gedaan.
https://dev.mysql.com/doc/c-api/8.0/en/getting-unique-id.html
For LAST_INSERT_ID(), the most recently generated ID is maintained in the server on a per-connection basis. It is not changed by another client. It is not even changed if you update another AUTO_INCREMENT column with a nonmagic value (that is, a value that is not NULL and not 0). Using LAST_INSERT_ID() and AUTO_INCREMENT columns simultaneously from multiple clients is perfectly valid. Each client will receive the last inserted ID for the last statement that client executed.
https://dev.mysql.com/doc/c-api/8.0/en/getting-unique-id.html
For LAST_INSERT_ID(), the most recently generated ID is maintained in the server on a per-connection basis. It is not changed by another client. It is not even changed if you update another AUTO_INCREMENT column with a nonmagic value (that is, a value that is not NULL and not 0). Using LAST_INSERT_ID() and AUTO_INCREMENT columns simultaneously from multiple clients is perfectly valid. Each client will receive the last inserted ID for the last statement that client executed.
Ah oke dat wist ik niet. Ik dacht dat hij het last inserted id van de hele tabel pakte. Dan kan ik de SELECT query inderdaad buiten de commit zetten.
Gewijzigd op 05/02/2021 16:21:40 door Snelle Jaap
Als ik in de handleiding kijk zie ik dat multi_query() uit zichzelf geen transacties uitvoert. De functie multi_query() voert alleen meerdere queries achter elkaar uit, waarbij je ongebruikte resultaten moet flushen voordat je query() weer kunt gebruiken. Je maak het iets gecompliceerder dan nodig.
Je kunt losse queries uitvoeren met mysqli::query(), zelfs een transactie starten met 'START TRANSACTION'. De AUTO_INCREMENT waarde kan je ook weer inlezen met mysqli::$insert_id, en hergebruiken in een volgende mysqli::query(). Dat lijkt mij overzichtelijker.