連載
» 2004年01月24日 00時00分 公開

基礎解説 ADO.NET基礎講座 ―初めての.NETデータベース・プログラミング―:第6回 データセットを使ったレコードの更新と削除 (1/4)

今回はデータセットに読み込んだレコードを編集し、それをデータベースに反映する。複数ユーザーからの同時アクセスについても考えてみる。

[デジタルアドバンテージ,著]
基礎解説 ADO.NET基礎講座 ―― 初めての.NETデータベース・プログラミング ―― 
Insider.NET

 

「基礎解説 ADO.NET基礎講座 ―― 初めての.NETデータベース・プログラミング ―― 」のインデックス

連載目次


 前回では、データセットとデータアダプタを利用した非接続型のデータベース・アクセスにおけるレコードの追加について解説した。続いて今回はレコードの更新について解説していく。

 念のため書いておくと、レコードの更新とは、すでにテーブルに存在するレコードに含まれているカラムのデータを新しい値で書き換えることである。通常、テーブルにはレコードを一意に識別できる主キーとなるカラム(あるいは複数のカラムの組み合わせ)が設定されている。従って、更新対象のレコードを主キーで指定し、そのカラムのデータを書き換えることになる。

 まずは、データセットにテーブルの内容を読み込み、その内容を書き換えるところから始める。

データセット内容の書き換え

 データセットにテーブルを読み込むまでは、すでに前回および前々回でも解説している。ここでもこれまでどおり、MSDEのサンプル・データベースであるpubsデータベースのpublishersテーブルからpub_idカラムとpub_nameカラムについて、すでに全レコードを取得しているとしよう。

 データテーブルのオブジェクトを変数dtで参照しているとすると、サンプル・データベースをインストールした直後では、dtから参照できる各レコードであるDataRowオブジェクトのデータは次の表のようになっているはずだ。

参照方法
dt.Rows[0]["pub_id"] 0736
dt.Rows[0]["pub_name"] New Moon Books
dt.Rows[1]["pub_id"] 0877
dt.Rows[1]["pub_name"] Binnet & Hardley
dt.Rows[2]["pub_id"] 1389
dt.Rows[2]["pub_name"] Algodata Infosystems
dt.Rows[3]["pub_id"] 1622
dt.Rows[3]["pub_name"] Five Lakes Publishing
dt.Rows[4]["pub_id"] 1756
dt.Rows[4]["pub_name"] Ramona Publishers
dt.Rows[5]["pub_id"] 9901
dt.Rows[5]["pub_name"] GGG&G
dt.Rows[6]["pub_id"] 9952
dt.Rows[6]["pub_name"] Scootney Books
dt.Rows[7]["pub_id"] 9999
dt.Rows[7]["pub_name"] Lucerne Publishing
データテーブルに読み込んだpublishersテーブルの初期値

 いま、データテーブル内にあるpub_idカラムの値が「1756」のレコードの、pub_nameカラムにある「Ramona Publishers」という値を「ラモーナ出版」と書き換えてみよう。これは単純に次のようなコードで記述できる。

dt.Rows[4]["pub_name"] = "ラモーナ出版";

 もちろんこの記述は、DataTalbeオブジェクトのDataRowオブジェクトのコレクションであるRowsプロパティの4番目のDataRowオブジェクトで、そのpub_idカラムの値が「1756」とすでに分かっている場合である。実際には、更新対象となるDataRowオブジェクトを見つけ出すことから始めなければならない。

更新対象レコードの取得

 データセット内から更新対象となるレコードを取り出す方法はいくつか用意されているが、主キーとなるカラムの値からレコードを取得するには、DataRowCollectionクラスのFindメソッドが利用できる。これは次のようにしてパラメータとして主キー・カラムの値を指定する。

DataRow targetRow = dt.Rows.Find("1756");

 今回対象としているpublishersテーブルには、主キーとして「pub_id」カラムが設定されており、そのカラムの型は文字列型である。

 ただし、このFindメソッドを利用する場合には、DataTableオブジェクト(ここでは変数dt)において、あらかじめ主キーを設定しておく必要がある。主キーの指定は、DataTableオブジェクトのPrimaryKeyプロパティに、主キーとなるカラムを表すDataColumnオブジェクトの配列をセットする。

dt.PrimaryKey = new DataColumn[] { dt.Columns["pub_id"] };

 カラムの配列を指定するのは、主キーが複数のカラムからなる場合があるためである。この例では主キーとなるカラムはpub_idカラムだけなので、配列の要素は1つだけとなる。

 さて、ここまでの手順を実行可能なプログラムとしてまとめておこう。次のサンプル・プログラムはpublishersテーブルからデータセットにレコードを読み込み、そのうちの「pub_id = "1756"」のレコードのpub_nameカラムを書き換える。まだ書き換えた内容をデーベースへは反映しない。

// updaterow.cs

using System;
using System.Data;
using System.Data.SqlClient;

public class UpdateDataRow {
  public static void Main() {
    string connStr = "Server=(local)\\NetSDK;"
                   + "Trusted_Connection=yes;"
                   + "database=pubs";
    string selectStr
      = "SELECT pub_id, pub_name FROM publishers";

    // 接続用オブジェクトの作成
    SqlConnection conn = new SqlConnection();
    conn.ConnectionString = connStr;

    // select用コマンド・オブジェクトの作成
    SqlCommand selectCmd = new SqlCommand();
    selectCmd.Connection = conn;
    selectCmd.CommandText = selectStr;

    // データアダプタの作成
    SqlDataAdapter da = new SqlDataAdapter();
    da.SelectCommand = selectCmd;

    // データセットへの読み込み
    DataSet ds = new DataSet();
    da.Fill(ds, "publishers");

    DataTable dt = ds.Tables["publishers"];

    // 主キーの設定
    dt.PrimaryKey = new DataColumn[] { dt.Columns["pub_id"] };

    // データの更新
    DataRow targetRow;
    targetRow = dt.Rows.Find("1756");
    targetRow["pub_name"] = "ラモーナ出版";
  }
}

// コンパイル方法:csc updaterow.cs

データベースからレコードを読み込み、データを更新するサンプル・プログラム(updaterow.cs)
updaterow.csのダウンロード

■Selectメソッドによるレコードの検索

 なお、データテーブルからレコードを主キーに関係なく検索するためのメソッドも用意されている。DataTableクラスのSelectメソッドである。このメソッドでは、パラメータに検索条件を文字列で指定できる。この検索条件はSQLのselect文のwhere句に指定する条件と似ている。

 Selectメソッドの利用例は次のようになる。

DataRow[] targetRows;
targetRows = dt.Select("pub_id = '1756'");

 また、例えばpub_nameカラムの値で検索する場合は次のようになる。

targetRows = dt.Select("pub_name = 'Ramona Publishers'");

 Selectメソッドでは、select文と同様にかなり多様な条件を指定することができ、レコードの並び替えなどの機能も用意されている。詳しくはリファレンス・マニュアルのSelectメソッドの項目を参照していただきたい。

 ただし主キーで検索する場合と異なり、Selectメソッドでは複数のDataRowオブジェクトが見つかる場合がある点には注意が必要だ。

■主キーを設定するための別の方法

 ところで、Findメソッドを使用する前に、なぜわざわざ主キーとなるカラムを自分で設定する必要があるのだろうか?

 第4回でも述べているように、データアダプタのFillメソッドは、レコードを読み込むのと同時にテーブルのカラム情報も取得しており、それらはDataColumnオブジェクトとしてデータテーブルのColumnsプロパティにセットされている。上記のサンプル・プログラムで、dt.Columns["pub_id"]としてpub_idカラムのDataColumnオブジェクトを指定できるのはこのためだ。

 しかし、デフォルトではテーブルに設定されている主キーについてのスキーマ情報はデータテーブルにはセットされない。これがデフォルトでないのは、主キーを含めたカラム情報の取得は処理に少し時間がかかるためだ。Fillメソッドの呼び出し時に主キー情報も取得するには、次のようにデータアダプタのMissingSchemaActionプロパティにMissingSchemaAction.AddWithKeyを設定すればよい(デフォルトの値はMissingSchemaAction.Add)。

// データアダプタの作成
SqlDataAdapter da = new SqlDataAdapter();
da.MissingSchemaAction = MissingSchemaAction.AddWithKey;
da.SelectCommand = selectCmd;

 もちろんこの場合には、データテーブルのPrimaryKeyプロパティの設定は不要である。この場合には、逆に次のようなコードにより主キーの情報にアクセスできる。このコードは主キーとなっているカラムのカラム名を表示する。

foreach (DataColumn dc in dt.PrimaryKey) {
  Console.WriteLine(dc.ColumnName);
}

 さらに別の方法としては、データアダプタのFillSchemaメソッドを使用してデータテーブルに主キー情報を設定することもできるが、これについてはここでは割愛させていただく。リファレンス・マニュアルの「DataSet への既存の制約の追加」にもあるように、主キーの設定は最適なパフォーマンスを得るためにPrimaryKeyプロパティを使用すべきである。プログラムで扱うテーブルの主キーが不明、ということはないはずだ。

       1|2|3|4 次のページへ

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。