Compartir a través de


Secuencias de Oracle

El proveedor de datos .NET Framework para Oracle proporciona compatibilidad para recuperar los valores clave de secuencia de Oracle que genera el servidor después de realizar inserciones con OracleDataAdapter.

SQL Server y Oracle admiten la creación de columnas de incremento automático que pueden designarse como claves principales. Estos valores los genera el servidor cuando se agregan filas a una tabla. En SQL Server se establece la propiedad Identity de una columna; en Oracle se crea una secuencia. La diferencia entre las columnas de incremento automático de SQL Server y las secuencias de Oracle es la siguiente:

  • En SQL Server, marca una columna como columna de incremento automático y SQL Server genera de forma automática nuevos valores para la columna cuando se inserta una nueva fila.
  • En Oracle, para generar nuevos valores en una columna de la tabla crea una secuencia, pero no existe vínculo directo entre la secuencia y la tabla o la columna. Las secuencias de Oracle son objetos, de la misma forma que las tablas o los procedimientos almacenados.

Cuando crea una secuencia en una base de datos de Oracle, puede definir su valor inicial y el incremento entre los valores. También puede consultar si existen nuevos valores en la secuencia antes de enviar nuevas filas. Esto implica que el código puede reconocer los valores clave de las nuevas filas antes de insertarlas en la base de datos.

Para más información sobre cómo crear columnas de incremento automático mediante SQL Server y ADO.NET, consulte Recuperación de valores de identidad o autonumeración y Creación de columnas de autoincremento.

Ejemplo

En el siguiente ejemplo de C# se muestra cómo puede recuperar nuevos valores de secuencia de una base de datos de Oracle. El ejemplo hace referencia a la secuencia de la consulta INSERT INTO utilizada para enviar nuevas filas y, a continuación, devuelve el valor de secuencia que se genera mediante la cláusula RETURNING introducida en Oracle10g. En el ejemplo se agrega una serie de filas nuevas pendientes en un objeto DataTable mediante el uso de la funcionalidad de incremento automático de ADO.NET para generar "marcadores de posición" de valores de clave principales. Tenga en cuenta que el valor de incremento que genera ADO.NET para la nueva fila es sólo un "marcador de posición". Esto significa que la base de datos puede generar valores distintos de los que genera ADO.NET.

Antes de enviar las inserciones pendientes a la base de datos, el ejemplo muestra el contenido de las filas. A continuación, el código crea un nuevo objeto OracleDataAdapter y establece sus propiedades InsertCommand y UpdateBatchSize. El ejemplo también proporciona la lógica para devolver los valores que genera el servidor mediante parámetros de salida. A continuación, ejecuta la actualización para enviar las filas pendientes y muestra el contenido del objeto 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();
   }
}

Consulte también