咨询:使用Dapper在Oracle中获取最后插入行ID(无需触发器/存储过程)
在Oracle中获取最后插入行的ID(无需触发器/存储过程)
针对你的场景(C# + Dapper/Dapper.Contrib,不想用触发器或存储过程),Oracle原生提供的RETURNING子句是最优解决方案,下面是具体实现方式:
方法1:使用Oracle的RETURNING子句(推荐,原子操作)
Oracle的RETURNING子句可以在插入语句执行完成后直接返回生成的ID值,整个操作是原子性的,能避免并发场景下的ID不一致问题。
代码示例
假设你的表结构如下(ID列由序列自动生成):
CREATE TABLE TEST_TABLE ( ID NUMBER PRIMARY KEY, NAME VARCHAR2(50) ); CREATE SEQUENCE SEQ_TEST_TABLE START WITH 1 INCREMENT BY 1; ALTER TABLE TEST_TABLE MODIFY ID DEFAULT SEQ_TEST_TABLE.NEXTVAL;
C#中使用Dapper执行插入并获取ID:
using Oracle.ManagedDataAccess.Client; using Dapper; var connString = "你的Oracle连接字符串"; var newRecord = new { Name = "测试数据" }; var outputId = new OracleParameter("outputId", OracleDbType.Int32, ParameterDirection.Output); using (var conn = new OracleConnection(connString)) { conn.Open(); var sql = "INSERT INTO TEST_TABLE (NAME) VALUES (:Name) RETURNING ID INTO :outputId"; conn.Execute(sql, new { newRecord.Name, outputId }); // 获取最后插入的ID var lastInsertedId = (int)outputId.Value; }
方法2:预获取序列值(适配Dapper.Contrib的Insert方法)
如果你想继续使用Dapper.Contrib的Insert方法,可以先手动获取序列的下一个值,再指定ID插入:
代码示例
using Oracle.ManagedDataAccess.Client; using Dapper.Contrib.Extensions; // 定义实体类 [Table("TEST_TABLE")] public class TestTable { [Key] public int ID { get; set; } public string Name { get; set; } } var connString = "你的Oracle连接字符串"; using (var conn = new OracleConnection(connString)) { conn.Open(); // 先获取序列的下一个值 var nextId = conn.QuerySingle<int>("SELECT SEQ_TEST_TABLE.NEXTVAL FROM DUAL"); // 创建实体并指定ID var newItem = new TestTable { ID = nextId, Name = "测试数据" }; // 使用Dapper.Contrib插入 conn.Insert(newItem); // nextId就是最后插入的ID }
注意:这种方法需要确保获取序列值和插入操作在同一个数据库会话中,序列本身是线程安全的,即使多会话同时获取序列值,也不会影响当前插入的ID正确性。
内容的提问来源于stack exchange,提问作者Flasher12
相关产品推荐
相关产品推荐

