Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 11.0.1 (日本語) » SQL Anywhere サーバ - プログラミング » SQL Anywhere データ・アクセス API » SQL Anywhere .NET データ・プロバイダ » データのアクセスと操作 » SADataAdapter オブジェクトを使用したデータのアクセスと操作

 

SADataAdapter オブジェクトを使用したローの挿入、更新、削除

SADataAdapter オブジェクトは、結果セットを DataSet に取り出します。DataSet は、テーブルのコレクションと、これらのテーブル間の関係と制約です。DataSet は、.NET Framework に組み込まれており、データベースへの接続に使用されるデータ・プロバイダとは関係ありません。

SADataAdapter を使用する場合、DataSet を設定し、DataSet の変更内容を使用してデータベースを更新するためにデータベースに接続されている必要があります。ただし、DataSet を一度設定すれば、データベースと切断されていても DataSet を修正できます。

変更内容をデータベースに即座に適用したくない場合、WriteXML を使用して DataSet (データかスキーマまたはその両方を含む) を XML ファイルに書き込むことができます。これによって、後で ReadXML メソッドを使用して DataSet をロードして変更を適用できるようになります。

詳細については、.NET Framework のマニュアルの WriteXML と ReadXML を参照してください。

Update メソッドを呼び出して変更を DataSet からデータベースに適用すると、SADataAdapter は、実行された変更を分析してから、必要に応じて適切な文 (INSERT、UPDATE、または DELETE) を呼び出します。DataSet を使用する場合、変更 (挿入、更新、または削除) を行うことができるのは、単一テーブルのデータのみです。ジョインに基づく結果セットは更新できません。更新しようとしているローを別のユーザがロックしている場合、例外がスローされます。

警告

DataSet を変更できるのは、接続が切断されている場合のみです。つまり、データベース内のこれらのローはアプリケーションによってロックされません。DataSet の変更がデータベースに適用されるときに発生する可能性がある競合を解消できるようアプリケーションを設計してください。これは、自分の変更がデータベースに適用される前に自分が修正しているデータを別のユーザが変更しようとするような場合です。

SADataAdapter を使用するときの競合の解消

SADataAdapter オブジェクトを使用する場合、データベース内のローはロックされません。つまり、DataSet からデータベースに変更を適用するときに競合が発生する可能性があります。このため、アプリケーションには、発生する競合を解消または記録する論理を採用する必要があります。

アプリケーション論理が対応すべき競合には、次のようなものがあります。

  • ユニークなプライマリ・キー   2 人のユーザが新しいローをテーブルに挿入する場合、ローごとにユニークなプライマリ・キーが必要です。オートインクリメント・プライマリ・キーがあるテーブルの場合、DataSet の値とデータ・ソースの値の同期がとれなくなる可能性があります。

    オートインクリメント・プライマリ・キーのプライマリ・キー値の取得に関する詳細については、プライマリ・キー値の取得を参照してください。

  • 同じ値に対して行われた更新   2 人のユーザが同じ値を修正する場合、どちらの値が正しいかを確認する論理をアプリケーションに採用する必要があります。

  • スキーマの変更   DataSet で更新したテーブルのスキーマを別のユーザが修正する場合、データベースに変更を適用するとこの更新が失敗します。

  • データの同時実行性   同時実行アプリケーションは、一連の一貫性のあるデータを参照する必要があります。SADataAdapter はフェッチするローをロックしないため、いったん DataSet を取り出してからオフラインで処理する場合、別のユーザがデータベース内の値を更新できます。

これらの潜在的な問題の多くは、SACommand、SADataReader、SATransaction オブジェクトを使用して変更をデータベースに適用することによって回避できます。このうち、SATransaction オブジェクトを使用することをおすすめします。これは、SATransaction オブジェクトを使用すると、トランザクションに独立性レベルを設定できるほか、他のユーザが修正できないようにローをロックできるためです。

トランザクションを使用して変更をデータに適用する方法の詳細については、SACommand オブジェクトを使用したローの挿入、更新、削除を参照してください。

競合の解消プロセスを簡素化するために、INSERT、UPDATE、DELETE 文をストアド・プロシージャ呼び出しとして設定できます。INSERT、UPDATE、DELETE 文をストアド・プロシージャに入れることによって、オペレーションが失敗したときのエラーを取得できます。文のほかにも、エラー処理論理をストアド・プロシージャに追加することによって、オペレーションが失敗したときに、エラーをログ・ファイルに記録したりオペレーションを再試行したりするなど、適切なアクションが行われるようにすることができます。

♦  SADataAdapter を使用してローをテーブルに挿入するには、次の手順に従います。
  1. SAConnection オブジェクトを宣言して初期化します。

    SAConnection   conn = new SAConnection(
        c_connStr );
  2. 接続を開きます。

    conn.Open();
  3. 新しい SADataAdapter オブジェクトを作成します。

    SADataAdapter adapter = new SADataAdapter();
    adapter.MissingMappingAction =
        MissingMappingAction.Passthrough;
    adapter.MissingSchemaAction =
        MissingSchemaAction.Add;
  4. 必要な SACommand オブジェクトを作成し、必要なパラメータを定義します。

    次のコードは、SELECT 文と INSERT 文を作成し、INSERT 文のパラメータを定義します。

    adapter.SelectCommand = new SACommand(
        "SELECT * FROM Departments", conn );
    adapter.InsertCommand = new SACommand(
        "INSERT INTO Departments( DepartmentID, DepartmentName )
        VALUES( ?, ? )", conn );
    adapter.InsertCommand.UpdatedRowSource =
        UpdateRowSource.None;
    SAParameter parm = new SAParameter();
    parm.SADbType = SADbType.Integer;
    parm.SourceColumn = "DepartmentID";
    parm.SourceVersion = DataRowVersion.Current;
    adapter.InsertCommand.Parameters.Add(
        parm );
    parm = new SAParameter();
    parm.SADbType = SADbType.Char;
    parm.SourceColumn = "DepartmentName";
    parm.SourceVersion = DataRowVersion.Current;
    adapter.InsertCommand.Parameters.Add( parm );
  5. DataTable に SELECT 文の結果を設定します。

    DataTable dataTable = new DataTable( "Departments" );
    int rowCount = adapter.Fill( dataTable );
  6. 新しいローを DataTable に挿入し、変更内容をデータベースに適用します。

    DataRow row1 = dataTable.NewRow();
    row1[0] = 600;
    row1[1] = "Eastern Sales";
    dataTable.Rows.Add( row1 );
    DataRow row2 = dataTable.NewRow();
    row2[0] = 700;
    row2[1] = "Western Sales";
    dataTable.Rows.Add( row2 );
    recordsAffected = adapter.Update( dataTable );
  7. 更新の結果を表示します。

    dataTable.Clear();
    rowCount = adapter.Fill( dataTable );
    dataGrid.DataSource = dataTable;
  8. 接続を閉じます。

    conn.Close();
♦  SADataAdapter オブジェクトを使用してローを更新するには、次の手順に従います。
  1. SAConnection オブジェクトを宣言して初期化します。

    SAConnection conn = new SAConnection( c_connStr );
  2. 接続を開きます。

    conn.Open();
  3. 新しい SADataAdapter オブジェクトを作成します。

    SADataAdapter adapter = new SADataAdapter();
    adapter.MissingMappingAction =
        MissingMappingAction.Passthrough;
    adapter.MissingSchemaAction =
        MissingSchemaAction.Add;
  4. SACommand オブジェクトを作成し、そのパラメータを定義します。

    次のコードは、SELECT 文と UPDATE 文を作成し、UPDATE 文のパラメータを定義します。

    adapter.SelectCommand = new SACommand(
        "SELECT * FROM Departments WHERE DepartmentID > 500",
        conn );
    adapter.UpdateCommand = new SACommand(
        "UPDATE Departments SET DepartmentName = ?
        WHERE DepartmentID = ?", conn );
    adapter.UpdateCommand.UpdatedRowSource =
        UpdateRowSource.None;
    SAParameter parm = new SAParameter();
    parm.SADbType = SADbType.Char;
    parm.SourceColumn = "DepartmentName";
    parm.SourceVersion = DataRowVersion.Current;
    adapter.UpdateCommand.Parameters.Add( parm );
    parm = new SAParameter();
    parm.SADbType = SADbType.Integer;
    parm.SourceColumn = "DepartmentID";
    parm.SourceVersion = DataRowVersion.Original;
    adapter.UpdateCommand.Parameters.Add( parm );
  5. DataTable に SELECT 文の結果を設定します。

    DataTable dataTable = new DataTable( "Departments" );
    int rowCount = adapter.Fill( dataTable );
  6. ローの更新値を使用して DataTable を更新し、変更内容をデータベースに適用します。

    foreach ( DataRow row in dataTable.Rows )
    {
    row[1] = ( string ) row[1] + "_Updated";
    }
    recordsAffected = adapter.Update( dataTable );
  7. 結果を画面上のグリッドにバインドします。

    dataTable.Clear();
    adapter.SelectCommand.CommandText =
        "SELECT * FROM Departments";
    rowCount = adapter.Fill( dataTable );
    dataGrid.DataSource = dataTable;
  8. 接続を閉じます。

    conn.Close();
♦  SADataAdapter オブジェクトを使用してローをテーブルから削除するには、次の手順に従います。
  1. SAConnection オブジェクトを宣言して初期化します。

    SAConnection conn = new SAConnection( c_connStr );
  2. 接続を開きます。

    conn.Open();
  3. SADataAdapter オブジェクトを作成します。

    SADataAdapter adapter = new SADataAdapter();
    adapter.MissingMappingAction =
        MissingMappingAction.Passthrough;
    adapter.MissingSchemaAction =
        MissingSchemaAction.AddWithKey;
  4. 必要な SACommand オブジェクトを作成し、必要なパラメータを定義します。

    次のコードは、SELECT 文と DELETE 文を作成し、DELETE 文のパラメータを定義します。

    adapter.SelectCommand = new SACommand(
        "SELECT * FROM Departments WHERE DepartmentID > 500",
        conn );
    adapter.DeleteCommand = new SACommand(
        "DELETE FROM Departments WHERE DepartmentID = ?",
        conn );
    adapter.DeleteCommand.UpdatedRowSource =
        UpdateRowSource.None;
    SAParameter parm = new SAParameter();
    parm.SADbType = SADbType.Integer;
    parm.SourceColumn = "DepartmentID";
    parm.SourceVersion = DataRowVersion.Original;
    adapter.DeleteCommand.Parameters.Add( parm );
  5. DataTable に SELECT 文の結果を設定します。

    DataTable dataTable = new DataTable( "Departments" );
    int rowCount = adapter.Fill( dataTable );
  6. DataTable を修正し、変更内容をデータベースに適用します。

    for each ( DataRow in dataTable.Rows )
    {
        row.Delete();
    }
    recordsAffected = adapter.Update( dataTable )
  7. 結果を画面上のグリッドにバインドします。

    dataTable.Clear();
    rowCount = adapter.Fill( dataTable );
    dataGrid.DataSource = dataTable;
  8. 接続を閉じます。

    conn.Close();