用于 Oracle 的 .NET Framework 数据提供程序支持在使用 OracleDataAdapter 执行插入后检索服务器生成的 Oracle 序列键值。
SQL Server 和 Oracle 支持创建可指派为主键的自动递增列。 在将行添加到表时,服务器将会生成这些值。 在 SQL Server 中,您可以设置列的标识属性;在 Oracle 中,您可以创建一个序列。 SQL Server 中自动递增列和 Oracle 中序列的区别是:
-
在 SQL Server 中,将某列标记为自动递增列,SQL Server 会在您插入新行时为该列自动生成新值。
-
在 Oracle 中,您创建一个序列以便为表中的列生成新值,但序列和表或列之间不存在直接链接。 Oracle 序列是一个类似表或存储过程的对象。
在 Oracle 数据库中创建序列时,您可以定义其初始值以及值之间的增量。 在提交新行之前,您也可以查询序列中的新值。 这意味着在您将新行插入数据库之前,代码可识别新行的键值。
有关使用 SQL Server 和 ADO.NET 创建自动递增列的更多信息,请参见检索标识或 Autonumber 值 (ADO.NET)和创建 AutoIncrement 列 (ADO.NET)。
下面的 C# 示例演示如何从 Oracle 数据库检索新序列值。 此示例引用用于提交新行的 INSERT INTO 查询中的序列,然后返回使用 Oracle10g 中引入的 RETURNING 子句生成的序列值。 此示例可使用 ADO.NET 自动递增功能在 DataTable 中添加一系列挂起的新行,以生成“占位符”主键值。 注意:ADO.NET 为新行生成的增量值仅是一个“占位符”。 这意味着数据库生成的值可能与 ADO.NET 生成的值不同。
在将挂起的插入行提交给数据库之前,此示例显示行的内容。 然后,代码将创建一个新的 OracleDataAdapter 对象并设置其 InsertCommand 和 UpdateBatchSize 属性。 此示例还提供使用输出参数返回服务器生成的值的逻辑。 然后,此示例将执行更新以提交挂起的行并显示 DataTable 的内容。
public void OracleSequence(String connectionString) { String insertString = "INSERT INTO SequenceTest_Table (ID, OtherColumn)" + "VALUES (SequenceTest_Sequence.NEXTVAL, :OtherColumn)" + "RETURNING ID INTO :ID"; using (OracleConnection conn = new OracleConnection(connectionString)) { //Open a connection. conn.Open(); OracleCommand cmd = conn.CreateCommand(); // Prepare the database. cmd.CommandText = "DROP SEQUENCE SequenceTest_Sequence"; try { cmd.ExecuteNonQuery(); } catch { } cmd.CommandText = "DROP TABLE SequenceTest_Table"; try { cmd.ExecuteNonQuery(); } catch { } cmd.CommandText = "CREATE TABLE SequenceTest_Table " + "(ID int PRIMARY KEY, OtherColumn varchar(255))"; cmd.ExecuteNonQuery(); cmd.CommandText = "CREATE SEQUENCE SequenceTest_Sequence " + "START WITH 100 INCREMENT BY 5"; cmd.ExecuteNonQuery(); DataTable testTable = new DataTable(); DataColumn column = testTable.Columns.Add("ID", typeof(int)); column.AutoIncrement = true; column.AutoIncrementSeed = -1; column.AutoIncrementStep = -1; testTable.PrimaryKey = new DataColumn[] { column }; testTable.Columns.Add("OtherColumn", typeof(string)); for (int rowCounter = 1; rowCounter <= 15; rowCounter++) { testTable.Rows.Add(null, "Row #" + rowCounter.ToString()); } Console.WriteLine("Before Update => "); foreach (DataRow row in testTable.Rows) { Console.WriteLine(" {0} - {1}", row["ID"], row["OtherColumn"]); } Console.WriteLine(); cmd.CommandText = "SELECT ID, OtherColumn FROM SequenceTest_Table"; OracleDataAdapter da = new OracleDataAdapter(cmd); da.InsertCommand = new OracleCommand(insertString, conn); da.InsertCommand.Parameters.Add(":ID", OracleType.Int32, 0, "ID"); da.InsertCommand.Parameters[0].Direction = ParameterDirection.Output; da.InsertCommand.Parameters.Add(":OtherColumn", OracleType.VarChar, 255, "OtherColumn"); da.InsertCommand.UpdatedRowSource = UpdateRowSource.OutputParameters; da.UpdateBatchSize = 10; da.Update(testTable); Console.WriteLine("After Update => "); foreach (DataRow row in testTable.Rows) { Console.WriteLine(" {0} - {1}", row["ID"], row["OtherColumn"]); } // Close the connection. conn.Close(); } }
oracle开发中序列的使用
序列是一数据库对象,利用它可生成唯一的整数。一般使用序列自动地生成主码值。一个序列的值是由特殊的Oracle程序自动生成,因此序列避免了在应用层实现序列而引起的性能瓶颈。Oracle序列允许同时生成多个序列号,而每一个序列号是唯一的。当一个序列号生成时,序列是递增,独立于事务的提交或回滚。允许设计缺省序列,不需指定任何子句。该序列为上升序列,由1开始,增量为1,没有上限。1) 建立序列命令
CREATE SEQUENCE [user.]sequence_name
[increment by n]
[start with n]
[maxvalue n | nomaxvalue]
[minvalue n | nominvalue];
INCREMENT BY: 指定序列号之间的间隔,该值可为正的或负的整数,但不可为0。序列为升序。忽略该子句时,缺省值为1。
START WITH:指定生成的第一个序列号。在升序时,序列可从比最小值大的值开始,缺省值为序列的最小值。对于降序,序列可由比最大值小的值开始,缺省值为序列的最大值。
MAXVALUE:指定序列可生成的最大值。
NOMAXVALUE:为升序指定最大值为1027,为降序指定最大值为-1。
MINVALUE:指定序列的最小值。
NOMINVALUE:为升序指定最小值为1。为降序指定最小值为-1026。2) 更改序列命令
ALTERSEQUENCE [user.]sequence_name
[INCREMENT BY n]
[MAXVALUE n| NOMAXVALUE ]
[MINVALUE n | NOMINVALUE];
修改序列可以:
? 修改未来序列值的增量。
? 设置或撤消最小值或最大值。
? 改变缓冲序列的数目。
? 指定序列号是否是有序。3) 删除序列命令
DROP SEQUENCE [user.]sequence_name;
从数据库中删除一序列。创建一个序列号的语句:
CREATE SEQUENCE EXAM_NO_SEQ START WITH 1484 MAXVALUE 9999999999 MINVALUE 1 CYCLE CACHE 20 NOORDER;PB中取序列号的用法:
string v_exam_no //获取申请序号 SELECT exam_no_seq.nextval INTO :v_exam_no FROM dual using ghis_database; if ghis_database.SQLCODE<>0 then messagebox("","取检查序号出错") return end if