W3Schools zegt:
If we perform an INSERT or UPDATE on a table with an AUTO_INCREMENT field, we can get the ID of the last inserted/updated record immediately: $last_id = $conn->insert_id;
Mijn testcode wordt dan :
$db = openDB(); // OO-functie de db-connectie afhandelt, werkt foutloos
if ($pid === 9999) $p = $db->query($qInsert); // zonder pid
else $p = $db->query($qUpdate); // met de optie WHERE pid='$pid'
$pid = $db->insert_id; // ZOU in allebei de gevallen de laatste AI-waarde moeten geven ?
$db->close();
print $pid; // geeft 0 dus waarschijnlijk NULL
<?php
error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', 1);
$dsn = 'mysql:host=localhost;dbname=test';
$username = 'root';
$password = '';
$dbh = new \PDO($dsn, $username, $password);
$dbh->query("
CREATE TABLE IF NOT EXISTS users (
user_id SMALLINT(5) UNSIGNED NOT NULL AUTO_INCREMENT,
first_name VARCHAR(255) NOT NULL,
PRIMARY KEY pk_user_id (user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci
");
// Drie records toevoegen: user_id 1, 2 en 3
$dbh->query("
INSERT INTO users (first_name)
VALUES ('Jan'), ('Piet'), ('Joris')
");
// Je zou user_id == 3 verwachten, maar dit is: string(1) "1"
var_dump($dbh->lastInsertId());
// Record 2 bijwerken
$dbh->query("
UPDATE users
SET first_name = 'Kees'
WHERE user_id = 2
");
// We hebben niets toegevoegd: string(1) "0"
var_dump($dbh->lastInsertId());
// Nog een record toevoegen: user_id wordt 4
$dbh->query("
INSERT INTO users (first_name)
VALUES ('Corneel')
");
// Nu wel juist: string(1) "4"
var_dump($dbh->lastInsertId());
// Nog drie records toevoegen: user_id 5, 6 en 7
$dbh->query("
INSERT INTO users (first_name)
VALUES ('Karen'), ('Kristel'), ('Kathleen')
");
// Je zou user_id == 7 verwachten: string(1) "5"
var_dump($dbh->lastInsertId());
?>
Bij de eerste INSERT met id 1, 2 en 3 is lastInsertId() 1; bij de derde INSERT met id 5, 6 en 7 is lastInsertId() 5. Het lijkt er dus op dat bij een INSERT van meerdere records de eerste id (1 en 5) wordt gebruikt. En dat is niet de hoogste id (3 en 7).
// Drie records toevoegen: user_id 1, 2 en 3
[...]
// Je zou user_id == 3 verwachten, maar dit is: string(1) "1"
Interessant. Waarom zou je dat verwachten? ;-)
Als je het insert_id opvraagt, doe je dat met een reden. Die reden is niet omdat je het id van het volgende record wilt berekenen (dat wordt immers gegenereerd door de database) maar waarschijnlijk omdat je de inserts wilt nabewerken. En in dat geval heb je meer aan het id van het eerste ingevoegde record dan aan dat van het laatste.
In software engineering zijn drie dingen moeilijk: naamgeving en tellen. Dit is zo'n voorbeeld van naamgeving. Een functienaam als id_of_first_inserted_record_for_latest_query() is ook niet de meest handige.
Het lijkt er dus op dat bij een INSERT van meerdere records de eerste id (1 en 5) wordt gebruikt.
Technisch gezien wordt het auto_increment-id gebruikt dat de tabel had vlak voor het eerste record werd ingevoegd. (En ja, ik heb ook de sourcecode van MySQL erbij gehaald. ;-) )
Dan is deze frisse blik onder de motorkap dus wat er in de documentatie ontbreekt:
Willem vp op 23/09/2016 08:50:28
En in dat geval heb je meer aan het id van het eerste ingevoegde record dan aan dat van het laatste.
[…]
Technisch gezien wordt het auto_increment-id gebruikt dat de tabel had vlak voor het eerste record werd ingevoegd.