Oracle シーケンス

更新 : November 2007

.NET Framework Data Provider for Oracle では、OracleDataAdapter を使用して挿入操作を実行した後、サーバーによって生成されたキー値 (Oracle シーケンス) を取得できます。

SQL Server および Oracle は、主キーとして指定できる自動増分列の作成をサポートします。これらの値はテーブルに行を追加するとサーバーによって自動的に生成されます。SQL Server では列の Identity プロパティを設定し、Oracle では Sequence を作成します。SQL Server の自動増分列と Oracle シーケンスの違いは、次のとおりです。

  • SQL Server では列を自動増分列として指定すると、新しい行を挿入するたびに SQL Server によって新しい列値が自動的に生成されます。

  • Oracle ではシーケンスを作成することによって、テーブルに新しい列値を生成します。ただし、シーケンスとテーブルまたはシーケンスと列の間に直接的な関係はありません。Oracle シーケンスは、テーブルやストアド プロシージャと同様のオブジェクトです。

Oracle データベースにシーケンスを作成する場合は、初期値と増分値を定義できます。新しい行を送信する前に、新しい値のシーケンスを照会することもできます。つまり、コードでデータベースに行を挿入する前に、新しい行のキー値を調べることができます。

SQL Server および ADO.NET を使用した自動増分列の作成の詳細については、「ID 値および 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 および ADO.NET