主表插入後,需將自增主鍵 ID 同步寫入關聯表(如:用戶主表 + 權限表、訂單主表 + 明細表)。關鍵函數:LAST_INSERT_ID()(SQL)/ mysql_insert_id()(PHP)。
<?php
// 1. 建立連線(啟用異常模式、UTF8MB4)
$dsn = "mysql:host=localhost;dbname=test;charset=utf8mb4";
$pdo = new PDO($dsn, 'charles', 'charles', [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
]);
try {
// 2. 開啟事務(保證原子性)
$pdo->beginTransaction();
// 3. 插入主表 contact
$sqlContact = "INSERT INTO contact (user_name, nom, prenom, mail, passcode)
VALUES (:user_name, :nom, :prenom, :mail, :passcode)";
$stmt = $pdo->prepare($sqlContact);
$stmt->execute([
'user_name' => 'sa',
'nom' => 'se',
'prenom' => 'sf',
'mail' => 'safd@p.com',
'passcode' => '123',
]);
// 4. 獲取自增 ID(關鍵步驟)
$lastId = $pdo->lastInsertId(); // 返回 BIGINT 字串
echo "Last insert ID: $lastId
";
// 5. 插入關聯表 contactdroit
$sqlDroit = "INSERT INTO contactdroit (contact_id, droit_id) VALUES (:cid, :did)";
$stmt = $pdo->prepare($sqlDroit);
$stmt->execute([
'cid' => $lastId,
'did' => 11,
]);
// 6. 提交事務
$pdo->commit();
echo "Good Insertion
";
echo "Inserted ID: $lastId";
} catch (PDOException $e) {
$pdo->rollBack();
die("Insert failed: " . $e->getMessage());
}
?>
| 函數 | 語言 | 返回值 | 作用域 | 注意事項 |
|---|---|---|---|---|
LAST_INSERT_ID() | SQL | BIGINT | 會話級 | 同一會話內不受其他連線影響;多行 INSERT 返回第一行 ID |
mysql_insert_id() | PHP (mysql_*) | int/false | 連線資源 | 已棄用,僅維護舊專案 |
PDO::lastInsertId() | PHP (PDO) | string | PDO 物件 | 推薦現代專案使用;支援序列名參數 (PostgreSQL) |
mysqli_insert_id() | PHP (mysqli) | int | mysqli 連線 | 程序式/物件式均可 |
INSERT INTO t (c) VALUES (1),(2),(3); 返回第一行 ID,連續 ID 需自行計算SET @saved_id = LAST_INSERT_ID(); 保存WITH ins AS (
INSERT INTO contact (user_name, nom, prenom, mail, passcode)
VALUES ('sa', 'se', 'sf', 'safd@p.com', '123')
)
INSERT INTO contactdroit (contact_id, droit_id)
SELECT LAST_INSERT_ID(), 11; -- 同一會話可用
限制:MySQL 不支援 RETURNING 子句(PostgreSQL/Oracle 有),CTE 寫法僅適用於單條主表插入場景。