程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> 【PHP】MySQL獲取插入數據的主鍵(自增加ID),mysql主鍵

【PHP】MySQL獲取插入數據的主鍵(自增加ID),mysql主鍵

編輯:關於PHP編程

【PHP】MySQL獲取插入數據的主鍵(自增加ID),mysql主鍵


 

為防止主鍵沖突,設計DB的時候常常使用自增加(auto_increment 型)字段。因此插入數據前往往不知道改記錄的主鍵是什麼,為了方便後續或級聯查詢,我們需要在插入一行記錄後獲得DB自動生成的主鍵。這裡稍微整理了下幾種方法:

 

  • DB中查詢

通用:

SELECT max(id) FROM user;

這個方法的缺點是不適合高並發。如果同時插入的時候返回的值可能不准確。

MySQL:

SELECT LAST_INSERT_ID();

重點: 假如你使用一條INSERT語句插入多個行, LAST_INSERT_ID() 只返回插入的第一行數據時產生的值。其原因是這使依靠其它服務器復制同樣的 INSERT語句變得簡單。

MS-SQL SERVER:

select @@IDENTITY;

@@identity是表示的是最近一次向具有identity屬性(即自增列)的表插入數據時對應的自增列的值,是系統定義的全局變量。一般系統定義的全局變量都是以@@開頭,用戶自定義變量以@開頭。比如有個表A,它的自增列是id,當向A表插入一行數據後,如果插入數據後自增列的值自動增加至101,則通過select @@identity得到的值就是101。使用@@identity的前提是在進行insert操作後,執行select @@identity的時候連接沒有關閉,否則得到的將是NULL值。


補充:
SCOPE_IDENTITY、IDENT_CURRENT 和 @@IDENTITY 在功能上相似,因為它們都返回插入到 IDENTITY 列中的值。 

IDENT_CURRENT 不受作用域和會話的限制,而受限於指定的表。IDENT_CURRENT 返回為任何會話和作用域中的特定表所生成的值。有關更多信息,請參見 IDENT_CURRENT。

SCOPE_IDENTITY 和 @@IDENTITY 返回在當前會話中的任何表內所生成的最後一個標識值。但是,SCOPE_IDENTITY 只返回插入到當前作用域中的值;@@IDENTITY 不受限於特定的作用域。

 

  • 服務器語言查詢

PHP: mysql_insert_id(connection);    or    mysqli_insert_id(connection);

參數   connection

描述   必需。規定要使用的 MySQL 連接。

<?php
$con = mysql_connect("localhost", "hello", "321");
if (!$con)
  {
  die('Could not connect: ' . mysql_error());
  }

$db_selected = mysql_select_db("test_db",$con);

$sql = "INSERT INTO person VALUES ('Carter','Thomas','Beijing')";
$result = mysql_query($sql,$con);
echo "ID of last inserted record is: " . mysql_insert_id();

mysql_close($con);
?>
<?php
$con=mysqli_connect("localhost","my_user","my_password","my_db");
// Check connection
if (mysqli_connect_errno($con))
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}

mysqli_query($con,"INSERT INTO Persons (FirstName,LastName,Age) 
VALUES ('Glenn','Quagmire',33)");

// Print auto-generated id
echo "New record has id: " . mysqli_insert_id($con); 

mysqli_close($con);
?>

 

補充:

PHP-MySQL 是 PHP 操作 MySQL 資料庫最原始的 Extension ,PHP-MySQLi 的 i 代表 Improvement ,提更了相對進階的功能,就 Extension 而言,本身也增加了安全性。

a. mysql與mysqli的概念相關:

  • mysql與mysqli都是php方面的函數集,與mysql數據庫關聯不大。
  • 在php5版本之前,一般是用php的mysql函數去驅動mysql數據庫的,比如mysql_query()的函數,屬於面向過程3、在php5版本以後,增加了mysqli的函數功能,某種意義上講,它是mysql系統函數的增強版,更穩定更高效更安全,與mysql_query()對應的有mysqli_query(),屬於面向對象,用對象的方式操作驅動mysql數據庫

b. mysql與mysqli的區別:

  • mysql是非持繼連接函數,mysql每次鏈接都會打開一個連接的進程。
  • mysqli是永遠連接函數,mysqli多次運行mysqli將使用同一連接進程,從而減少了服務器的開銷。mysqli封裝了諸如事務等一些高級操作,同時封裝了DB操作過程中的很多可用的方法。

c. mysql與mysqli的用法:

  • mysql(過程方式):
$conn = mysql_connect('localhost', 'user', 'password'); //連接mysql數據庫
mysql_select_db('data_base');     //選擇數據庫
$result = mysql_query('select * from data_base');//第二個可選參數,指定打開的連接
$row = mysql_fetch_row( $result ) ) //只取一行數據
echo $row[0]; //輸出第一個字段的值

PS:mysqli以過程式的方式操作,有些函數必須指定資源,比如mysqli_query(資源標識,SQL語句),並且資源標識的參數是放在前面的,而mysql_query(SQL語句,'資源標識')的資源標識是可選的,默認值是上一個打開的連接或資源。

  • mysqli(對象方式):
$conn = new mysqli('localhost', 'user', 'password','data_base');  //要使用new操作符,最後一個參數是直接指定數據庫
//假如構造時候不指定,那下一句需要$conn -> select_db('data_base')實現

$result = $conn -> query( 'select * from data_base' );
$row = $result -> fetch_row(); //取一行數據
echo row[0]; //輸出第一個字段的值

使用new mysqli('localhost', usenamer', 'password', 'databasename');會報錯,提示如下:

Fatal error: Class 'mysqli' not found in ...

一般是mysqli是沒有開啟的,因為mysqli類不是默認開啟的,win下要改php.ini,去掉php_mysqli.dll前的;,linux下要把mysqli編譯進去。

d. mysql_connect()與mysqli_connect()

  • 使用mysqli,可以把數據庫名稱當作參數傳給mysqli_connect()函數,也可以傳遞給mysqli的構造函數;
  • 如果調用mysqli_query()或mysqli的對象查詢query()方法,則連接標識是必需的。

JDBC 2.0:insertRow()

Statement stmt = null;
ResultSet rs = null;
try {
    stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,  // 創建Statement
                                java.sql.ResultSet.CONCUR_UPDATABLE);
    stmt.executeUpdate("DROP TABLE IF EXISTS autoIncTutorial");
    stmt.executeUpdate(                                                // 創建demo表
            "CREATE TABLE autoIncTutorial ("
            + "priKey INT NOT NULL AUTO_INCREMENT, "
            + "dataField VARCHAR(64), PRIMARY KEY (priKey))");
    rs = stmt.executeQuery("SELECT priKey, dataField "                 // 檢索數據
       + "FROM autoIncTutorial");
    rs.moveToInsertRow();                                              // 移動游標到待插入行(未創建的偽記錄)
    rs.updateString("dataField", "AUTO INCREMENT here?");              // 修改內容
    rs.insertRow();                                                    // 插入記錄
    rs.last();                                                         // 移動游標到最後一行
    int autoIncKeyFromRS = rs.getInt("priKey");                        // 獲取剛插入記錄的主鍵preKey
    rs.close();
    rs = null;
    System.out.println("Key returned for inserted row: "
        + autoIncKeyFromRS);
}  finally {
    // rs,stmt的close()清理
}

JDBC 3.0:getGeneratedKeys()

Statement stmt = null;
ResultSet rs = null;
try {
    stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
                                java.sql.ResultSet.CONCUR_UPDATABLE);  
    // ...
    // 省略若干行(如上例般創建demo表)
    // ...
    stmt.executeUpdate(
            "INSERT INTO autoIncTutorial (dataField) "
            + "values ('Can I Get the Auto Increment Field?')",
            Statement.RETURN_GENERATED_KEYS);                      // 向驅動指明需要自動獲取generatedKeys!
    int autoIncKeyFromApi = -1;
    rs = stmt.getGeneratedKeys();                                  // 獲取自增主鍵!
    if (rs.next()) {
        autoIncKeyFromApi = rs.getInt(1);
    }  else {
        // throw an exception from here
    } 
    rs.close();
    rs = null;
    System.out.println("Key returned from getGeneratedKeys():"
        + autoIncKeyFromApi);
}  finally { ... }

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved