本文是以.Net的编码方式演示如何不使用存储过程获取Oracle的序列值,方便开发者在插入数据库记录时间获取当前ID等关键字段。
声明
- 为了简化使用了OracleHeper类;
- CALENDAR是日程表,只有一个CALENDAR_ID字段;
- SEQ_CALENDAR_ID为序列(sequence);
方法一,先获取序列,然后把序列当做值插入数据库
- 优点:代码简单直观,易懂;
- 缺点:需要两次交互,性能不佳;
- 注意事项:记得关闭Reader;
public int AddCalendar_First() { int calendarId = 0; try { string sql = "SELECT SEQ_CALENDAR_ID.NEXTVAL FROM DUAL"; IDataReader idr = OracleHelper.ExecuteReader(CommandType.Text, sql); if (idr.Read()) { calendarId = int.Parse(idr[0].ToString()); } idr.Close(); sql = "INSERT INTO CALENDAR(CALENDAR_ID)VALUES(:PARME_CALENDAR_ID)"; OracleParameter[] parmes = { new OracleParameter("PARME_CALENDAR_ID", OracleDbType.Int32) }; OracleHelper.ExecuteNonQuery(CommandType.Text, sql, parmes); } catch (Exception ex) { //记录日志 } return calendarId;}
- 优点:适用于后期不易改造程序的妥协;
- 缺点:需要两次交互,性能不佳;
- 注意事项:虽然声称序列是使用的回话隔离,但如果多个应用并发访问一个库,将长生混乱;
public int AddCalendar_Second() { int calendarId = 0; try { string sql = "INSERT INTO CALENDAR(CALENDAR_ID)VALUES(SEQ_CALENDAR_ID.NEXTVAL)"; OracleHelper.ExecuteNonQuery(CommandType.Text, sql, null); IDataReader idr = OracleHelper.ExecuteReader(CommandType.Text, "SELECT SEQ_CALENDAR_ID.CURRVAL FROM DUAL"); if (idr.Read()) { calendarId = int.Parse(idr[0].ToString()); } idr.Close(); } catch (Exception ex) { //记录日志 } return calendarId;}
方法三 使用returning into语法
- 优点:性能最好;
- 缺点:目前没发现;
- 注意事项:记得设置Direction类型;
public int AddCalendar_Third() { int calendarId = 0; try { string sql = "INSERT INTO CALENDAR(CALENDAR_ID)VALUES(SEQ_CALENDAR_ID.NEXTVAL) RETURNING CALENDAR_ID INTO :ID"; OracleParameter[] parmes = { new OracleParameter("ID",OracleDbType.Int32) }; parmes[0].Direction = ParameterDirection.ReturnValue; OracleHelper.ExecuteNonQuery(CommandType.Text, sql, parmes); calendarId = int.Parse(parmes[0].Value.ToString()); } catch (Exception ex) { //记录日志 } return calendarId;}
三种方法中方法三最佳,可考虑使用。