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();
}
}