検索
連載

第5回 データセットを使ったレコードの追加基礎解説 ADO.NET基礎講座 ―初めての.NETデータベース・プログラミング―(3/3 ページ)

非接続型であるデータセットを使った場合のレコード追加について解説。ADO.NETには必要なSQL文を自動作成する機能も用意されている。

Share
Tweet
LINE
Hatena
前のページへ |       

自動作成されたinsert文

 SqlCommandBuilderクラスによって自動作成されるinsert文というのは実際にはどのようなものだろうか。その内容は次のようなコードにより確認することができる。

// showcb.cs

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

public class ShowBuildCommand {
  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(connStr);
    SqlDataAdapter da = new SqlDataAdapter(selectStr, conn);

    SqlCommandBuilder cb = new SqlCommandBuilder(da);
    SqlCommand insert = cb.GetInsertCommand();

    Console.WriteLine(insert.CommandText);

    foreach (SqlParameter p in insert.Parameters) {
      Console.WriteLine(p.ParameterName);
      Console.WriteLine(p.SourceColumn);
    }
  }
}

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

自動生成されたinsert文を表示するサンプル・プログラム(showcb.cs)
showcb.csのダウンロード

 ここではSqlCommandBuilderクラスのインスタンスを作成したときに得られるオブジェクト(cb)を捨てずに利用している。このクラスのGetInsertCommandメソッドは、insert文を直ちに作成させるためのメソッドである。

 このプログラムを実行した結果は次のようになる。

INSERT INTO publishers( pub_id , pub_name ) VALUES ( @p1 , @p2 )
@p1
pub_id
@p2
pub_name

サンプル・プログラム(showcb.cs)の実行結果

 上記のプログラムでは、SqlCommandBuilderオブジェクトのParametersプロパティにより、insert文と同時に自動生成された名前付きパラメータの情報(の一部)も表示している。名前付きパラメータの名前は異なるが、表示されたinsert文は先ほどのサンプル・プログラムのものと(まねたわけではないが)同一である。

 では、SqlCommandBuilderクラスはこのinsert文をどうやって作り出しているのだろうか。データアダプタにセットしたselect文を基にしているのはまちがいないようだが、単にそれだけではないのは、それを次のように変更してプログラムを実行すれば分かる。

SELECT * FROM publishers

 このように変更したときの出力は次のようになる。

INSERT INTO publishers( pub_id , pub_name , city , state , country ) VALUES ( @p1 , @p2 , @p3 , @p4 , @p5 )
@p1
pub_id
@p2
pub_name
@p3
city
@p4
state
@p5
country

select文を変更した場合のサンプル・プログラム(showcb.cs)の実行結果

 この実行結果からも分かるように、SqlCommandBuilderクラスでは、データベースに接続して列の情報を取り出し、それを基にしてinsert文を作成しているのである。このため自前でinsert文を用意するのに比べると、データベースへの余分な問い合わせが1つ増える。Updateメソッドを呼ぶ瞬間までinsert文が自動作成されないようになっているのも、このためであると思われる。

SQLプロファイラによるデータベース処理のトレース

 念のため、先に示したレコードの追加を行う2つのサンプル・プログラム(insertds.csとcbinsertds.cs)において、実際にデータベース・サーバに発行されるSQL文を確認してみよう。

 SQL Server 2000には、このような用途のために「SQLプロファイラ」というツールが付属している。このツールでは、あらかじめ対象となるデータベース・サーバを指定しておけば、発行されたすべてのSQL文をトレースすることができる。

 次の画面は、SQLプロファイラによるトレースを開始してから、まず最初のサンプル・プログラム(insertds.cs)を実行した後の状態だ。


サンプル・プログラム(insertds.cs)実行時のトレース結果
Fillメソッド呼び出し時に発行されたselect文と、Updateメソッド呼び出し時に発行されたinsert文が実行されているのが分かる。

 一方、insert文の自動生成を利用したサンプル・プログラム(cbinsertds.cs)のトレース結果は次のようになる。


サンプル・プログラム(cbinsertds.cs)実行時のトレース結果
上のトレース結果に比べて、insert文の自動生成に必要なselect文を含む行が増えている。

 見慣れないコマンドはとりあえず置いておくとして、2つの結果を比べると、自動生成させた方のトレース結果には次のようなselect文を含む行が、insert文の直前で余分に実行されているのが分かる。

SET FMTONLY OFF; SET NO_BROWSETABLE ON; SET FMTONLY ON;SELECT pub_id, pub_name FROM publishers SET FMTONLY OFF; SET NO_BROWSETABLE OFF;

 これがSqlCommandBuilderクラスによるinsert文自動生成のための問い合わせである。データベースの更新頻度にもよるが、当然ながらこの余分なselect文の発行はアプリケーションのパフォーマンスを悪くするので、SqlCommandBuilderクラスの多用には注意が必要となる。

データアダプタ構成ウィザードによるinsert文の自動生成

 SqlCommandBuilderクラスはselect文から動的にinsert文を作り出すことができるが、select文が固定であるなら(ほとんどのアプリケーションはそうであると思われるが)、それに対して自動作成されるinsert文もいつも同じである。そのような場合、わざわざ実行時にinsert文を作り出す必要はない。極端な話、select文以外を自分で書きたくないなら、SqlCommandBuilderクラスを使用したツールを作っておいて、出力されたinsert文をプログラムにコピー&ペーストしてからコンパイルすれば、余分な問い合わせを減らすことができる。

 Visual Studio .NETを使用してデータベース・アプリケーションを作成している方ならご存じだと思うが、VS.NETの「データアダプタ構成ウィザード」はまさにそれを行っている。Visual Studio .NETによるデータベース・プログラミングは、本連載でも今後取り上げる予定だが、ここではウィザードにより作成されたinsert文について簡単に見ておこう。

 データアダプタ構成ウィザードは、ツールボックスの[データ]から[SqlDataAdapter]の項目をフォーム上にドラッグ&ドロップしたときなどに自動的に起動される。


データアダプタ構成ウィザードの起動画面
データアダプタ構成ウィザードは、ツールボックスの[データ]から[SqlDataAdapter]の項目をフォーム上にドラッグ&ドロップしたときなどに自動的に起動される。

 ウィザードによる設定手順の途中には、アプリケーションで使用するselect文を入力する画面がある(クエリ・ビルダによりGUIでselect文を作成することもできる)。


データアダプタ構成ウィザードのselect文の入力画面

 この画面で[次へ]ボタンをクリックするときに、SqlCommandBuilderクラス(あるいはそれに似たクラス)を利用しているようである。SQLプロファイラのトレースを実行していると、クリックしたときに先ほどと同じselect文が実行されているのを確認することができる。

 ウィザードでの作業が完了すると、insert文やupdate文、delete文が自動生成され、名前付きパラメータの設定のためのコードとともに、プログラム・コードが自動生成される。データアダプタの作成からinsert文の作成までのコードは次のようになっている。


データアダプタ構成ウィザードにより自動生成されたコード(一部抜粋)

 このようにVisual Studio .NETのデータアダプタ構成ウィザードでは、「自動生成されたinsert文を含んだSqlCommandオブジェクトを作成するコード」を自動生成することにより、すべてをコンパイル時に済ませるようになっている。


 今回はデータセットを使った場合のレコードの追加について解説してきた。次回はこれに引き続いて、レコードの更新と削除について解説する予定だ。実は今回では、データセットに追加された新しいレコードをどうやってデータアダプタが見つけ出すかということについて触れていない。これについても次回で解説する予定である。

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

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

前のページへ |       

Copyright© Digital Advantage Corp. All Rights Reserved.

ページトップに戻る