PHP Conference Japan 2024

mysqli::$insert_id

mysqli_insert_id

(PHP 5, PHP 7, PHP 8)

mysqli::$insert_id -- mysqli_insert_id傳回最後一個查詢為 AUTO_INCREMENT 欄位產生的值

說明

物件導向風格

程序風格

mysqli_insert_id(mysqli $mysql): int|string

在含有 `AUTO_INCREMENT` 屬性欄位的資料表上執行 `INSERT` 或 `UPDATE` 查詢後,會傳回產生的 ID。如果是多行 `INSERT` 陳述式,它會傳回第一個成功插入的自動產生值。

使用 `LAST_INSERT_ID()` MySQL 函數執行 `INSERT` 或 `UPDATE` 陳述式也會修改 mysqli_insert_id() 傳回的值。如果使用 `LAST_INSERT_ID(expr)` 來產生 `AUTO_INCREMENT` 的值,它會傳回最後一個 `expr` 的值,而不是產生的 `AUTO_INCREMENT` 值。

如果先前的陳述式沒有更改 `AUTO_INCREMENT` 值,則傳回 `0`。mysqli_insert_id() 必須在產生值的陳述式之後立即呼叫。

參數

mysql

僅限程序式風格:由 mysqli_connect()mysqli_init() 傳回的 mysqli 物件。

傳回值

由前一個查詢更新的 `AUTO_INCREMENT` 欄位的值。如果連線上沒有先前的查詢,或者查詢沒有更新 `AUTO_INCREMENT` 值,則傳回零。

只有使用目前連線發出的陳述式才會影響傳回值。使用其他連線或用戶端發出的陳述式不會影響該值。

注意事項:

如果數字大於整數最大值,則會以字串形式傳回。

範例

範例 #1 $mysqli->insert_id 範例

物件導向風格

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

$mysqli->query("CREATE TABLE myCity LIKE City");

$query = "INSERT INTO myCity VALUES (NULL, 'Stuttgart', 'DEU', 'Stuttgart', 617000)";
$mysqli->query($query);

printf("新紀錄的 ID 為 %d。\n", $mysqli->insert_id);

/* 刪除表格 */
$mysqli->query("DROP TABLE myCity");

程序風格

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

mysqli_query($link, "CREATE TABLE myCity LIKE City");

$query = "INSERT INTO myCity VALUES (NULL, 'Stuttgart', 'DEU', 'Stuttgart', 617000)";
mysqli_query($link, $query);

printf("New record has ID %d.\n", mysqli_insert_id($link));

/* 刪除表格 */
mysqli_query($link, "DROP TABLE myCity");

以上範例會輸出

New record has ID 1.
新增筆記

使用者貢獻的筆記 9 則筆記

will at phpfever dot com
18 年前
我收到許多聲明指出 insert_id 屬性存在錯誤,因為它「有時會起作用」。請記住,使用物件導向方法時,mysqli 類別的實際實例將會保存 insert_id。

以下程式碼將不會返回任何內容。
<?php
$mysqli
= new mysqli('host','user','pass','db');
if (
$result = $mysqli->query("INSERT INTO t (field) VALUES ('value');")) {
echo
'ID 為: '.$result->insert_id;
}
?>

這是因為 insert_id 屬性不屬於結果,而是屬於實際的 mysqli 類別。以下程式碼會正常運作

<?php
$mysqli
= new mysqli('host','user','pass','db');
if (
$result = $mysqli->query("INSERT INTO t (field) VALUES ('value');")) {
echo
'The ID is: '.$mysqli->insert_id;
}
?>
mmulej at gmail dot com
3 年前
目前還沒有使用預處理語句的範例。

```php
$u_name = "John Doe";
$u_email = "johndoe@example.com";

$stmt = $connection->prepare(
"INSERT INTO users (name, email) VALUES (?, ?)"
);
$stmt->bind_param('ss', $u_name, $u_email);
$stmt->execute();

echo $stmt->insert_id;
```

對於 UPDATE,您只需相應地更改查詢字串和綁定參數,其餘部分保持不變。

當然,表格需要具有 AUTOINCREMENT PRIMARY KEY。
adrian dot nesse dot wiik at gmail dot com
1 年前
如果您嘗試使用 ON DUPLICATE KEY UPDATE 插入一行,請注意,如果觸發了 ON DUPLICATE KEY UPDATE 子句,則 insert_id 不會更新。

仔細想想,這實際上非常合乎邏輯,因為 ON DUPLICATE KEY UPDATE 是一個 UPDATE 語句,而不是 INSERT。

在最壞的情況下,如果您正在迭代某些內容並執行 INSERT,同時在後續程式碼中依賴 insert_id,則在觸發 ON DUPLICATE KEY UPDATE 的迭代中,您可能指向錯誤的行!
bert at nospam thinc dot nl
16 年前
請注意 $db->insert_id 的物件導向風格用法。當 insert_id 超過 2^31 (2147483648) 時,擷取插入 ID 會呈現錯誤的、過大的數字。您最好改用程序式 mysqli_insert_id( $db )。

[由 danbrown AT php DOT net 編輯:這是 32 位元帶符號整數限制的另一個主要示例。]
www dot wesley at gmail dot com
5 年前
使用 "INSERT ... ON DUPLICATE KEY UPDATE `id` = LAST_INSERT_ID(`id`)" 時,InnoDB 表中的 AUTO_INCREMENT 會增加,但 MyISAM 表中的 AUTO_INCREMENT 不會增加。
Nick Baicoianu
17 年前
在具有 AUTO_INCREMENT 欄位的表格上執行擴展插入時,mysqli_insert_id() 的值將等於插入的*第一*行的值,而不是您可能預期的最後一行的值。

<?
//mytable 有一個 auto_increment 欄位
$db->query("INSERT INTO mytable (field1,field2,field3) VALUES ('val1','val2','val3'),
('val1','val2','val3'),
('val1','val2','val3')");

echo $db->insert_id; //將會顯示插入的第一行的 ID
?>
jpage at chatterbox dot fyi
1 年前
目前尚不清楚的是併發控制如何影響這個函式。當您連續兩次呼叫 mysql,且第二次的結果取決於第一次時,另一個使用者可能在此期間進行了插入操作。

文件中並未提及此事,所以我總是在插入前後確定自動遞增值,以防範這種情況。
alan at commondream dot net
20 年前
我在獲取插入的 ID 時遇到了一些問題,並進行了一些測試。結果是,如果您在獲取最後插入的 ID 之前提交事務,它每次都會返回 0,但如果您在提交事務之前獲取最後插入的 ID,則會獲得正確的值。
owenzx at gmail dot com
11 年前
這個例子缺少 multi_query 中的 insert_id。以下是我的例子
假設你在 mysql 中有一個新的 test_db,像這樣

建立資料庫,如果不存在則建立 test_db;
使用 test_db;
建立表格 user_info (_id serial, name varchar(100) not null);
建立表格 house_info (_id serial, address varchar(100) not null);

然後你執行一個像這樣的 php 檔案

<?php
define
('SERVER', '127.0.01');
define('MYSQL_USER', 'your_user_name');
define('MYSQL_PASSWORD', 'your_password');

$db = new mysqli(SERVER, MYSQL_USER, MYSQL_PASSWORD, "test_db", 3306);
if (
$db->connect_errno)
echo
"建立資料庫失敗,錯誤訊息:", $db->connect_error;
else {
$sql = "insert into user_info "
. "(name) values "
. "('owen'), ('john'), ('lily')";
if (!
$result = $db->query($sql))
echo
"新增資料失敗,錯誤訊息:", $db->error;
else
echo
"此查詢新增的最後一筆 ID 為 ", $db->insert_id, "\n";
$sql = "insert into user_info"
. "(name) values "
. "('jim');";
$sql .= "insert into house_info "
. "(address) values "
. "('shenyang')";
if (!
$db->multi_query($sql))
echo
"使用 multi_query 新增資料失敗,錯誤訊息:", $db->error;
else {
echo
"第一次 multi_query 新增的最後一筆 ID 為 ", $db->insert_id, "\n";
if (
$db->more_results() && $db->next_result())
echo
"第二次 multi_query 新增的最後一筆 ID 為 ", $db->insert_id, "\n";
else
echo
"使用 multi_query 新增資料失敗,第二個查詢錯誤訊息:", $db->error;
}
$db->close();
}
?>

您會得到如下輸出:

此查詢新增的最後一筆 ID 為 1
第一次 multi_query 新增的最後一筆 ID 為 4
第二次 multi_query 新增的最後一筆 ID 為 1

結論
1. insert_id 在 multi_query 中有效。
2. 如果一次新增多筆資料,insert_id 會返回 MySQL 使用的第一個 ID。
To Top