2010-02-05 88 views
5

我正確理解mysql的LAST_INSERT_ID()函數在插入嘗試之間沒有重置(因爲@@ identity在sql-server中)...如果立即前面的插入操作失敗,LAST_INSERT_ID()將返回任何該連接的最後一個插入的pk的pk爲任意表中包含自動遞增主鍵。如果我在這方面是正確的,這是否看起來不像是關於這個功能的最遲鈍的行爲,而是人們可以想到的?是否沒有與sql-server的@@標識類似的mysql函數?如果前面的插入嘗試創建沒有新的記錄將返回NULL?或者,如何確定最新插入操作的主鍵?mysql @@ identity vs sql-server last_insert_id()

+5

@@身份爲您提供最新的在任何範圍內插入。這可能是觸發器的結果,與您剛剛運行的插入語句無關。在SQL服務器中,您通常希望使用scope_identity()函數。 – feihtthief 2010-02-05 18:20:58

+0

@feihtthief - thx,很好的說明+1 – codemonkey 2010-02-05 18:22:10

+0

請注意,當SQL Server的@@ identity和scope_identity()與多處理器的服務器上的多行插入一起使用時,可能會給出錯誤的答案!使用OPTION(MAXDOP 1)是一種解決方法。 – ErikE 2010-02-06 01:31:09

回答

6

@@ identity在sql server中通常也是錯誤的。在大多數情況下,您應該使用scope_identity()

在MySql中,last_insert_id()應該是安全的,因爲插入錯誤後您可以調用此函數的唯一方法是您已經正確捕獲並解釋了插入錯誤。否則,你仍然會在處理命令。換句話說,last_insert_id()不是你的錯誤處理機制。

+0

@paragraph 2 - 讓我重新思考構造插入語句的方式......在這種情況下,提供插入的select語句的where子句決定插入是否發生。換句話說,根據where子句的條件,插入是0+條記錄。我想我可以拉外插入和有條件地執行插入。很好的解決方法,但它確實感覺像我的解決方法。 – codemonkey 2010-02-05 18:29:57

1

您必須先檢查插入是否成功。如果插入成功,則可以依賴LAST_INSERT_ID()。

編輯:在PHP中:

<?php 
$link = mysql_connect('localhost', 'mysql_user', 'mysql_password'); 
if (!$link) { 
    die('Could not connect: ' . mysql_error()); 
} 
mysql_select_db('mydb'); 

mysql_query('<PUT YOUR INSERT HERE'); 
if(mysql_affected_rows()>0){ 
    $last_id=mysql_insert_id(); 
}else{ 
    //panic! 
} 
?> 
+0

我不知道是否有一個本地mysql函數類似於php的msyql_affected_rows()?我們所有的dml都作爲存儲過程/函數駐留在數據庫中。 – codemonkey 2010-02-05 18:31:34

+0

http://php.net/manual/en/function.mysql-query.php對於其他類型的SQL語句,INSERT,UPDATE,DELETE,DROP等,mysql_query()在成功時返回TRUE或在錯誤時返回FALSE。 – Notinlist 2010-02-05 18:43:34

+1

插入語句可能「成功」,並且不會進行任何插入。考慮INSERT IGNORE語句。在這種情況下,依靠mysql_query()的返回值會產生錯誤的結果。 – 2010-02-05 21:21:06