多資料庫支援系統中,INSERT 後取得自動增長鍵值的方式不一:
JDBC 3.0 引入 Statement.getGeneratedKeys() 標準化此需求,但 SQL Server 2000 驅動不支援。SQL Server 2005 JDBC 驅動(版本 1.1+)完整支援 JDBC 3.0,成為統一解決方案的關鍵。
sqljdbc.jar,放入 Tomcat `common/lib` 或專案 `WEB-INF/lib`(若為共享主機需確認提供商支援)。| 項目 | SQL Server 2000 驅動 | SQL Server 2005 驅動 |
|---|---|---|
| JDBC 版本 | 2.0 | 3.0(支援 getGeneratedKeys) |
| URL 格式 | jdbc:microsoft:sqlserver://host:1433;DatabaseName=db | jdbc:sqlserver://host:1433;DatabaseName=db |
| Driver Class | com.microsoft.jdbc.sqlserver.SQLServerDriver | com.microsoft.sqlserver.jdbc.SQLServerDriver |
| 套件結構 | com.microsoft.jdbc.* | com.microsoft.sqlserver.* |
⚠️ 常見錯誤:URL 或 Driver Class 混用 2000/2005 格式會導致 ClassNotFoundException 或 Cannot load JDBC driver。
public String executeInsert(String sql) throws SQLException {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = getConnection(); // 自行實現連線池取得
// 關鍵:指定 RETURN_GENERATED_KEYS
pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
pstmt.executeUpdate();
rs = pstmt.getGeneratedKeys(); // 取得自動產生的鍵值 ResultSet
if (rs.next()) {
return rs.getString(1); // 通常第 1 欄為身分識別欄
}
return "-1";
} catch (SQLException ex) {
throw new SQLException("執行 SQL 失敗: " + ex.getMessage() + " sql: " + sql, ex);
} finally {
closeQuietly(rs);
closeQuietly(pstmt);
closeQuietly(conn);
}
}
prepareStatement(sql, Statement.RETURN_GENERATED_KEYS) 必須指定,否則 `getGeneratedKeys()` 拋出「只有運行該語句,生成的鍵才會可用」。IDENTITY 欄位的 INSERT 有效;若為 `INSERT ... SELECT` 或合併語句行為視驅動版本而定。升級至 SQL Server 2005 JDBC 驅動,配合 JDBC 3.0 標準介面,即可在多資料庫架構中以同一套程式碼安全、高效地取得自動增長鍵值,消除併發風險與程式碼分支。