2024 年 PHP Conference Japan

mysql_insert_id

(PHP 4, PHP 5)

mysql_insert_id取得上一個查詢產生的 ID

警告

此擴充套件已於 PHP 5.5.0 中棄用,並已於 PHP 7.0.0 中移除。建議改用 MySQLiPDO_MySQL 擴充套件。另請參閱 MySQL:選擇 API 指南。此函式的替代方案包括:

說明

mysql_insert_id(資源 $link_identifier = NULL): 整數

擷取前一個查詢(通常是 INSERT)為 AUTO_INCREMENT 欄位產生的 ID。

參數

link_identifier

MySQL 連線。如果未指定連結識別碼,則假設為 mysql_connect() 開啟的最後一個連結。如果找不到此類連結,它會嘗試建立一個連結,如同以無參數呼叫 mysql_connect() 一樣。如果找不到或建立連線,則會產生 E_WARNING 等級的錯誤。

返回值

成功時,返回前一個查詢為 AUTO_INCREMENT 欄位產生的 ID;如果前一個查詢未產生 AUTO_INCREMENT 值,則返回 0;如果未建立 MySQL 連線,則返回 false

範例

範例 #1 mysql_insert_id() 範例

<?php
$link
= mysql_connect('localhost', 'mysql_user', 'mysql_password');
if (!
$link) {
die(
'無法連線: ' . mysql_error());
}
mysql_select_db('mydb');

mysql_query("INSERT INTO mytable (product) values ('kossu')");
printf("最後插入的記錄 ID 為 %d\n", mysql_insert_id());
?>

注意事項

警告

mysql_insert_id() 會將原生 MySQL C API 函式 mysql_insert_id() 的返回類型轉換為 long 類型(在 PHP 中稱為 int)。如果您的 AUTO_INCREMENT 欄位的欄位類型為 BIGINT(64 位元),則轉換可能會導致值不正確。此時,請在 SQL 查詢中使用內部 MySQL SQL 函式 LAST_INSERT_ID()。有關 PHP 最大整數值的更多資訊,請參閱 整數 文件。

備註:

因為 mysql_insert_id() 作用於最後執行的查詢,所以請務必在產生值的查詢之後立即呼叫 mysql_insert_id()

備註:

MySQL SQL 函式 LAST_INSERT_ID() 的值始終包含最近產生的 AUTO_INCREMENT 值,並且在查詢之間不會重置。

另請參閱

新增註釋

使用者貢獻的註釋 11 則註釋

Alfred Nony Mouse
16 年前
使用自動遞增欄位本身並沒有錯。使用其主要競爭方案,也就是由資料庫提供一組非重複的識別碼(通常是整數)也沒有錯。這就好比你開車要靠哪邊行駛一樣。

更大的問題是人們不了解他們在進行資料庫存取時的操作。這就像在不真正了解交通規則的情況下開車。這樣的人會在不知不覺中做出錯誤的決定,最終導致某些問題發生。

資料庫是複雜的,值得花時間去真正理解。學習不同解決問題方法的含義和限制。這樣,您就能夠根據實際情況選擇合適的解決方案。
foros (_AT_) anthalia.com
17 年前
不要使用 MAX 來獲取最後插入的 ID。競爭條件,例如其他使用者在您的 SELECT MAX(.. 和 INSERT 之間插入數據,可能會導致您的 ID 無法使用。

獲取 ID 的正確方法是使用 mysql_insert_id() 或 MySQL SQL 函數 LAST_INSERT_ID()。

請注意,如果使用 mysql_insert_id(),您應該提供 mysql_connect 返回的資源,而不是 mysql_query 返回的結果集。
elinor dot hurst at REMOVETHIS dot gmail dot com
16 年前
我不太明白這有什麼好大驚小怪的。

我讀到
「mysql_insert_id() 的值僅受當前客戶端連線中發出的語句影響。它不受其他客戶端發出的語句影響。」

參見:https://mysqldev.dev.org.tw/doc/refman/5.0/es/mysql-insert-id.html

我真的看不出這有什麼不準確之處。

「如果是多行 INSERT 語句,mysql_insert_id() 會返回第一個自動生成的 AUTO_INCREMENT 值;如果沒有生成這樣的值,它會返回最後插入到 AUTO_INCREMENT 欄位中的顯式值。」

我一定是遺漏了什麼,但為什麼要插入多行,然後只用一些偏好的行為處理最後一行呢?您也可以一次插入一行,然後使用最新的 ID 分別處理每一行。

我看不出這有什麼問題。

然而,我可以看到僅使用 max(my_table.id_column) 的問題所在,因為這會導致併發存取的問題。
athies at gmail dot com
19 年前
快速說明一下。 mysql_insert_id() 確實適用於 REPLACE。
bargainbatman at gmail dot com
15 年前
我認為這與所有使用 mysqli 並在 INSERT 命令後尋找 ID 的人有關

<?php
function insert_join($catid, $disc_id) {
// 插入新的項目到資料庫
$conn = db_connect();
// 插入新項目
$demande = "insert into categories_disc values ('', '".$catid."', '".$disc_id."')";
$resultat = $conn->query($demande);
if (!
$resultat) {
return
false;
} else {
return
$conn->insert_id; // 這個函式現在會回傳 ID 而不是 true。
}

}
?>

接著,在另一端,我們可以這樣呼叫這個函式:

<?php
$cat_id
= insert_join($catid, $disc_id);
if(
$cat_id !== false) {

echo
"<p>類別資料已新增至資料庫,如下所示:<br>";
echo
"<hr>類別 ID:".$cat_id."</p><hr>";

}
?>
匿名
19 年前
請注意要為 AUTO_INCREMENT 欄位設定空值,否則 mysq_insert_id() 回傳的值永遠不會是零以外的數字。

Ciao Ephraim
hoangvu4000 at gmail dot com
11 年前
如何在 MySQL 中取得最後更新列的 ID?

75
down vote
我找到這個問題的答案了 :)

by Pomyk

SET @update_id := 0;
UPDATE some_table SET row = 'value', id = (SELECT @update_id := id)
WHERE some_other_row = 'blah' LIMIT 1;
SELECT @update_id;
由 aefxx 編輯

這個技巧可以進一步擴展,以取得受 update 陳述式影響的每一列的 ID

SET @uids := null;
UPDATE footable
SET foo = 'bar'
WHERE fooid > 5
AND ( SELECT @uids := CONCAT_WS(',', fooid, @uids) );
SELECT @uids;
這會回傳一個字串,其中包含所有以冒號串連的 ID。

(問題來源:stackoverflow,編號 1388025)
heiligkind at yahoo dot de
18 年前
如果您使用 INSERT 陳述式中的 ON DUPLICATE KEY UPDATE 子句插入資料列,mysql_insert_id() 函式回傳的結果將與您直接在 MySQL 中使用 LAST_INSERT_ID() 的結果不同。

請參考以下範例

<?
// 插入一筆資料列,主鍵為 auto_increment
// value 是一個唯一鍵值
$query = "INSERT INTO test (value) VALUES ('test')";
mysql_query( $query );

echo 'LAST_INSERT_ID: ',
mysql_query( "SELECT LAST_INSERT_ID()" ),
'<br>mysql_insert_id: ',
mysql_insert_id();

?>

這會印出

LAST_INSERT_ID: 1
mysql_insert_id: 1

在這種情況下,函式的返回值與 MySQL 陳述式相同。
但請參考在現有鍵值上插入的情況

<?
$query = "INSERT INTO test (value)
VALUES ('test')
ON DUPLICATE KEY UPDATE value = 'test2'";
mysql_query( $query );

echo 'LAST_INSERT_ID: ',
mysql_query( "SELECT LAST_INSERT_ID()" ),
'<br>mysql_insert_id: ',
mysql_insert_id();

?>

這會印出

LAST_INSERT_ID: 2
mysql_insert_id: 1

使用 ON DUPLICATE KEY UPDATE 子句時,如果 INSERT 陳述式造成重複的項目,則只會修改舊的資料列,但 LAST_INSERT_ID() 函式會傳回主鍵的下一個自動遞增值,順帶一提,這個值並不會被設定為資料庫中的下一個自動遞增值。

mysql_insert_id() 函式會傳回舊的(已更改的)資料列的主鍵。對我來說,這是正確的操作方法,因為 LAST_INSERT_ID() 函式傳回的值根本沒有參考任何資料列。

來自慕尼黑的問候。

heiligkind
louis at intoplay dot com
17 年前
如果 mysql_insert_id() 傳回 0 或 null,請檢查您的自動遞增欄位是否沒有被您的 SQL 查詢設定,如果您像我一樣有多個資料庫連線,解決方案是為此查詢建立一個獨立的資料庫連線。
vksgeneric at hotmail dot com
24 年前
您不能執行 INSERT DELAYED 並期望獲得非零的值,因為它是在一個獨立的執行緒中執行的,而 mysql_insert_id() 是與目前的執行緒綁定的。
Vlad
dhiraj dot webdeveloper at gmail dot com
7 年前
MySQLi 程序式
//---------------------------------------------
$last_id = mysqli_insert_id($conn);

//---------------------------------------------
<?php
$servername
= "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";

// 建立連線
$conn = mysqli_connect($servername, $username, $password, $dbname);
// 檢查連線
if (!$conn) {
die(
"連線失敗: " . mysqli_connect_error());
}

$sql = "INSERT INTO MyGuests (firstname, lastname, email)
VALUES ('John', 'Doe', 'john@example.com')"
;

if (
mysqli_query($conn, $sql)) {
$last_id = mysqli_insert_id($conn);
echo
"新增記錄成功。最後插入的 ID 為: " . $last_id;
} else {
echo
"錯誤: " . $sql . "<br>" . mysqli_error($conn);
}

mysqli_close($conn);
?>
To Top