摘要:但是,最近在使用的過程中發(fā)現(xiàn)有時候函數(shù)返回的是。返回最后插入行的或序列值。結(jié)果主鍵是字段,不使用自增約束。結(jié)果查看源碼可以看到,有些例子返回,有些例子返回最新的。因此,在沒有使用約束的表中,或者是自己生成的唯一,函數(shù)返回的都是。
原文地址 : http://www.hoohack.me/2016/01/19/the-reason-why-lastInsertId-return-0/
問題在使用PHP的PDO擴展插入數(shù)據(jù)的時候,有時候需要獲取到最后插入記錄的ID作為返回信息。要怎么才能實現(xiàn)這個需求呢?
lastInsertId函數(shù)使用PDO的lastInsertId函數(shù)。
但是,最近在使用的過程中發(fā)現(xiàn)有時候lastInsertId函數(shù)返回的是0。為什么會這樣呢?
先來看看lastInsertId函數(shù)在PHP手冊上的說明。
返回最后插入行的ID或序列值。
再來看看下面的幾個例子。
測試?yán)?/b> 主鍵是ID字段,使用自增約束。getMessage(); } for( $i = 0; $i < 10; $i++){ $sql = "INSERT INTO `tbl_test` (id, name) VALUE (:id, :name)"; $data = array( ":id" => "", ":name" => "user_$i" ); $sth = $dbh->prepare($sql); $sth->execute($data); } $sql = "INSERT INTO `tbl_test` (id, name) VALUE (:id, :name)"; $new_data = array( ":id" => "", ":name" => "user_new" ); $sth = $dbh->prepare($sql); $sth->execute($new_data); $last_id = $dbh->lastInsertId(); echo "last id: " . $last_id;
結(jié)果
主鍵是ID字段,不使用自增約束。last id: 11
getMessage(); } for( $i = 0; $i < 10; $i++){ $sql = "INSERT INTO `tbl_test` (id, name) VALUE (:id, :name)"; $data = array( ":id" => $i, ":name" => "user_$i" ); $sth = $dbh->prepare($sql); $sth->execute($data); } $sql = "INSERT INTO `tbl_test` (id, name) VALUE (:id, :name)"; $new_data = array( ":id" => "", ":name" => "user_new" ); $sth = $dbh->prepare($sql); $sth->execute($new_data); $last_id = $dbh->lastInsertId(); echo "last id: " . $last_id;
結(jié)果
主鍵不是ID字段,主鍵使用自增約束。last id: 0
getMessage(); } for( $i = 0; $i < 10; $i++){ $sql = "INSERT INTO `tbl_test` (tbl_id, name) VALUE (:tbl_id, :name)"; $data = array( ":tbl_id" => $i, ":name" => "user_$i" ); $sth = $dbh->prepare($sql); $sth->execute($data); } $sql = "INSERT INTO `tbl_test` (tbl_id, name) VALUE (:tbl_id, :name)"; $new_data = array( ":tbl_id" => "", ":name" => "user_new" ); $sth = $dbh->prepare($sql); $sth->execute($new_data); $last_id = $dbh->lastInsertId(); echo "last id: " . $last_id;
結(jié)果
主鍵不是ID字段,不使用自增約束。last id: 11
getMessage(); } for( $i = 0; $i < 10; $i++){ $sql = "INSERT INTO `tbl_test` (tbl_id, name) VALUE (:tbl_id, :name)"; $data = array( ":tbl_id" => uniqid(), ":name" => "user_$i" ); $sth = $dbh->prepare($sql); $sth->execute($data); } $sql = "INSERT INTO `tbl_test` (tbl_id, name) VALUE (:tbl_id, :name)"; $new_data = array( ":tbl_id" => uniqid(), ":name" => "user_new" ); $sth = $dbh->prepare($sql); $sth->execute($new_data); $last_id = $dbh->lastInsertId(); echo "last id: " . $last_id;
結(jié)果
查看PHP源碼last id: 0
可以看到,有些例子返回0,有些例子返回最新的ID。那么lastInsertId什么情況下會返回0呢?在網(wǎng)上搜了很多資料,并沒有發(fā)現(xiàn)想要的答案,翻開PHP源碼,發(fā)現(xiàn)函數(shù)last_insert_id的實現(xiàn)源碼是這樣的:
可以看到,函數(shù)返回的id的值是調(diào)用mysql api中的mysql_insert_id函數(shù)返回的值。
查看mysql手冊翻開mysql手冊,在這里找到這一段:
結(jié)論mysql_insert_id() returns the value stored into an AUTO_INCREMENT column, whether that value is automatically generated by storing NULL or 0 or was specified as an explicit value. LAST_INSERT_ID() returns only automatically generated AUTO_INCREMENT values. If you store an explicit value other than NULL or 0, it does not affect the value returned by LAST_INSERT_ID().
從手冊的描述可以知道,mysql_insert_id函數(shù)返回的是儲存在有AUTO_INCREMENT約束的字段的值,如果表中的字段不使用AUTO_INCREMENT約束或者使用自己生成的唯一值插入,那么該函數(shù)不會返回你所存儲的值,而是返回NULL或0。因此,在沒有使用AUTO_INCREMENT約束的表中,或者ID是自己生成的唯一ID,lastInsertId函數(shù)返回的都是0。
解決方案那么,有沒有另一種方法可以幫助我們判斷程序執(zhí)行插入是否成功呢?答案是有的。在PDO執(zhí)行了excecute之后,調(diào)用PDO實例的rowCount函數(shù)可以得到執(zhí)行之后的影響行數(shù),如果結(jié)果非0,那么說明數(shù)據(jù)庫插入操作執(zhí)行成功了。下面這個解決方案的一小段demo:
$sql = "INSERT INTO `tbl_test` (tbl_id, name) VALUE (:tbl_id, :name)"; $new_data = array( ":tbl_id" => uniqid(), ":name" => "user_another" ); $sth = $dbh->prepare($sql); $sth->execute($new_data); $row_count = $sth->rowCount(); if( $row_count ){ echo "execute success"; } else{ echo "execute failed"; }
本文探討一個問題出現(xiàn)的原因和一個解決方案,由于個人水平有限,如有更好的方法或者其他建議和批評,歡迎指出。
注:本文使用的是PHP5.4.15,MySQL5.5.41。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/30296.html
摘要:同樣的,添加屬性,修改函數(shù)構(gòu)造語句的方法基類中添加方法檢測有沒有設(shè)置子句構(gòu)建語句參數(shù)綁定返回影響的行數(shù)更新數(shù)據(jù)示例相比,語句更為簡單,只需子句即可。 查詢語句 (DQL) 的構(gòu)造功能開發(fā)完畢,我們再給查詢構(gòu)造器增加一些對 DML (Data Manipulation Language) 語句的支持,如簡單的 insert、update、delete 操作。 insert 我們先回顧下 ...
摘要:二對象利用的構(gòu)造函數(shù)連接特定的數(shù)據(jù)庫,創(chuàng)建一個對象。連接數(shù)據(jù)庫連接數(shù)據(jù)庫有三種方式通過參數(shù)形式連接推薦構(gòu)造函數(shù)還有一個參數(shù),它是一個數(shù)組,用于配置運行中的數(shù)據(jù)庫,如是否開啟自動提交設(shè)置結(jié)果集的返回方式等。 一、PDO簡介 PDO是PHP Data Object的簡稱,用于定義數(shù)據(jù)庫訪問的抽象層,統(tǒng)一各種數(shù)據(jù)庫的訪問接口。PDO有如下特性: 編碼一致性:PDO支持多種數(shù)據(jù)庫擴展,并為...
摘要:操作數(shù)據(jù)庫的種形式使用擴展類庫推薦使用擴展類庫這是類庫的升級版,但已經(jīng)不推薦使用擴展包含哪三個類與區(qū)別可以支持多種數(shù)據(jù)庫,而且操作方法一致只支持?jǐn)?shù)據(jù)庫如何使用連接數(shù)據(jù)庫什么是如何關(guān)閉連接通過來連接數(shù)據(jù)庫,其中必須傳入數(shù)據(jù)源名稱數(shù)據(jù)源名稱是 PHP操作數(shù)據(jù)庫的2種形式 使用 PDO 擴展類庫(推薦) 使用 Mysqli 擴展類庫(這是Mysql類庫的升級版,但已經(jīng)不推薦使用) PDO...
閱讀 3763·2021-10-13 09:39
閱讀 3811·2021-09-24 09:48
閱讀 1206·2021-09-01 10:30
閱讀 2538·2019-08-30 15:55
閱讀 1788·2019-08-29 16:39
閱讀 2307·2019-08-26 13:55
閱讀 3063·2019-08-26 12:23
閱讀 1645·2019-08-26 11:59