首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

各大數據庫 INSERT 同時獲取自增 ID 原子操作方案對比

     編輯:MySQL 綜合教學

核心需求

INSERT 寫入數據的同時,原子性獲取自增主鍵 ID,**避免「先查 MAX(ID)+1 再插入」的併發競態條件**。

Oracle:RETURNING INTO 子句


-- SQL
INSERT INTO KEYWORD (KEYWORD_ID, SITE_ID, KEYWORD_NAME, STATUS, SOURCE, CREATE_TIME, LAST_CHANGED)
VALUES (KEYWORD_SEQ.NEXTVAL, :SITE_ID, :NAME, 1, :SOURCE, SYSDATE, SYSDATE+0.0007)
RETURNING KEYWORD_ID INTO :Key_ID;

-- Java (JDBC/OracleDriver)
OracleParameter outputIdParm = new OracleParameter(":Key_ID", OracleDbType.Int32, ParameterDirection.Output);
command.Parameters.Add(outputIdParm);
command.ExecuteNonQuery();
var allKeyWordIds = outputIdParm.Value as OracleDecimal[];

關鍵點:RETURNING ... INTO + ParameterDirection.Output,單次往返完成寫入+取 ID。

SQL Server:@@IDENTITY / SCOPE_IDENTITY() / IDENT_CURRENT()


-- T-SQL
INSERT INTO syslog (Thread) VALUES ('test');
SELECT @@IDENTITY AS Id;  -- 或 SCOPE_IDENTITY() (推薦,不受觸發器影響)

-- C# (ADO.NET)
var cmd = conn.CreateCommand();
cmd.CommandText = "INSERT INTO syslog (Thread) VALUES ('test'); SELECT SCOPE_IDENTITY();";
var id = cmd.ExecuteScalar();  -- 直接返回標量值

區別**:@@IDENTITY 返回會話最後生成的身份值 (含觸發器副作用);SCOPE_IDENTITY() 返回當前作用域 (存儲過程/觸發器/批次) 最後生成值,**推薦用 SCOPE_IDENTITY()**;IDENT_CURRENT('table') 返回表最後生成值 (跨會話,併發不安全)。

MySQL:LAST_INSERT_ID() / JDBC getGeneratedKeys()


-- SQL 方式
INSERT INTO t (name) VALUES ('test');
SELECT LAST_INSERT_ID();  -- 返回當前會話最後生成的 AUTO_INCREMENT 值

-- JDBC 標準方式 (推薦,跨數據庫兼容)
String sql = "INSERT INTO t (name) VALUES (?)";
try (PreparedStatement ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
    ps.setString(1, "test");
    ps.executeUpdate();
    try (ResultSet rs = ps.getGeneratedKeys()) {
        if (rs.next()) {
            long id = rs.getLong(1);  -- 獲取自增 ID
        }
    }
}

-- MyBatis 配置

    INSERT INTO user (name, age) VALUES (#{name}, #{age})


關鍵點**:

  • LAST_INSERT_ID() 是**會話級**函數,併發安全,不受其他會話影響
  • Statement.RETURN_GENERATED_KEYS 是 JDBC 3.0 標準,**首選方案**,屏蔽數據庫差異
  • 批量插入時,getGeneratedKeys() 返回所有生成的 ID (順序對應),LAST_INSERT_ID() 僅返回第一條

PostgreSQL:RETURNING 子句


INSERT INTO t (name) VALUES ('test') RETURNING id;
-- 直接返回結果集,單條或批量均支持

總結對比表

數據庫標準 SQL 方案驅動層標準方案備註
OracleRETURNING INTOOraclePreparedStatement + registerReturnParameter序列 SEQ.NEXTVAL 生成 ID
SQL ServerSCOPE_IDENTITY()Statement.RETURN_GENERATED_KEYS (JDBC 4.0+ 支持)避免用 @@IDENTITY
MySQLLAST_INSERT_ID()Statement.RETURN_GENERATED_KEYS (首選)批量插入獲取所有 ID
PostgreSQLRETURNING idStatement.RETURN_GENERATED_KEYS功能最強,可返回任意列
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved