none
TableAdapterにおけるODBCデータベースへのパラメタライズドクエリについて RRS feed

  • 質問

  • ASP .NETの初心者です。

    今まではボーランド系の開発ツールを使用してWindowsアプリを作成していましたが、現在はWebアプリを作成しながら.NET Frameworkについて勉強しています。

     

    そういう中で分からないところが出てきましたので、お助けください。

     

    VWD2008のTableAdapterを使用してODBCで繋げたデータベースとの接続をデータアクセスコンポーネントを使用してウィザードに従い作成しています。

    パラメータのないSELECTについては問題なくデータを取り出すことが出来たのですが、パラメータを設定したクエリを作成した場合はウィザードの最後に、「DbType Object から周知の型 OdbcType へのマッピングは存在しません」と表示されます。無理やりウィザード完了させると、テーブルアダプタにクエリは作成されるのですが、もちろんデバッグするとエラーになります。しかし、後から作成されたクエリのプロパティからクエリビルダを開き、それを実行させると正常に動作します。

    テーブルアダプタ内のSQL分は以下のような記述です。

    SELECT MAIL_ADD FROM MAIL_USER WHERE USER_NAME = ?

     

    OdbcDataAdapter クラスというのがありますが、そちらを使うべきなのかもよくわかりません。

     

    少し初歩的な質問かも知れませんが、よろしくお願いいたします。

     

     

     

     

     

    2008年5月14日 2:47

回答

  • 自動翻訳で日本語が変なんですが、以下のページが関連しそうです。

     

    データアダプタ構成ウィザードを使って、 OdbcDataAdapter を構成するとき、「マッピングが何も DbType オブジェクト から既知の OdbcType に存在しない」エラーが発生する A

    http://support.microsoft.com/kb/816802

     

    2008年5月14日 3:26
    モデレータ
  •  401k さんからの引用

    ツールボックスのアイテム一覧の中には確かにOdbcDataAdapterコントロールはありますが、チェックを入れてもツールボックスに現れてくれません。

     

    VS2005の時からそうなってしまいました。

    ODBCではOdbcDataAdapterを使わなければならないというわけではなく、TableAdapterでパラメタライズドクエリも使えます。ただ、作成されたSQL文がおかしなことも稀にあるようなので、作成されたSQL文を確認された方が良いと思います。

    2008年5月16日 7:24
    モデレータ
  • App_Code フォルダを右クリック → [新しい項目の追加]をクリック → [データ
    セット]を選択 → 名前をつけて[追加]ボタンをクリック → ツールボックスから
    TableAdapter をドラッグ&ドロップ → ウィザードに従って DataSet と TableAdapter
    を作成されていると思いますが、そうであれば、

     

    C:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\[Webサイト名]\********\********\Sources_App_Code

     

    というフォルダーの中に、

     

    xsdファイル名.********.cs

     

    という名前のファイル(自動生成されたDataSet と TableAdapter)があるはずですの
    で、それを見てみてはいかがでしょう。

     

    自動生成さた TableAdapter の中には適切な DataAdapter がメンバーに含まれてい
    るのではないでしょうか(この場合は OdbcDataAdapter)?

     

    ちなみに、自分は VWD 2008 Express Edition をデフォルトで使っていますが、その
    ツールボックスには OdbcDataAdapter コントロールというのは見当たりません。です
    から、環境に違いがあって上記は外れているかもしれません。その場合は失礼しまし

    た。

    2008年5月17日 7:18
  •  401k さんからの引用

    簡単なSQL文をいろいろ試してみましたが、やはりエラーになります。

    SELECT ”取り出す列名” FROM ”テーブル名” WHERE ”条件列名” = ?

     

    まず、ウィザードで、条件なしで全アイテムを抽出する SELECT クエリを
    作ってから、TableAdapter に条件付 SELECT クエリを加えるようにしては
    いかがでしょう?

     

    手順は下記のようになります。

     

    (1) App_Code フォルダを右クリック
    (2) [新しい項目の追加]をクリック
    (3) [データセット]を選択
    (4) 名前をつけて[追加]ボタンをクリック
    (5) ツールボックスから TableAdapter をドラッグ&ドロップ

     

    (6) まず、条件なしで全アイテムを抽出する SELECT クエリを作成。
      手順は、TableAdapter 構成ウィザードに従って、
      ・データ接続の選択 → コマンドの種類を選択(SQL ステートメント
       を使用する) → SQL ステートメントの入力と進み、そこでクエリ
       ビルダで * にチェックを入れて条件なし全選択クエリを作成
      ・生成するメソッドの選択 → ウィザードの結果、と進んで正常に
       作成されたことを確認して完了。

     

    (7) 次に、TableAdapter に条件付 SELECT クエリを追加。
      手順は、

     (7-1) 表示されている TableAdapter の箱の中にツールボックスから
        Query をドラッグ&ドロップ

     (7-2) TableAdapter クエリの構成ウィザードに従って、
      ・コマンドの種類を選択 → クエリの種類の選択(複数行を返す
       SELECT) → SQL SELECT ステートメントの指定と進んで、クエリ
       ビルダ上で選択条件の列の「フィルタ」欄に =? と入力。出力しな
       い項目はチェックを外すなどしたあと、OK ボタンをクリックして
       SELECT クエリを作成
      ・生成するメソッドの選択 → ウィザードの結果、と進んで正常に
       作成されたことを確認して完了。

     

    これでもダメですと、あとは、手作業でコードを書いて、それをウィザ
    ードで作った TableAdapter(partial クラスとして定義されています)
    に合体させるぐらいしか方法は思いつきません。

     

    上記のようなことは言われなくても百も承知ということでしたら失礼し

    ました。

    2008年5月20日 2:43
  • すみません、間違えました。

     

    上のメッセージで (7-2) で「出力しない項目はチェックを外すなどしたあと」と書きま

    したが、チェックを外すと (6) で作成された DataTable と合わなくなってエラーにな

    ります。

    2008年5月20日 11:52
  • クエリは正しいのに、何故かウィザードが正しくないと判断してエラーを出す
    ということのようですね。

     

    そうすると、ウィザードを使っての対応は、すみませんが自分としてはお手上
    げです。

     

    先の手順 (6) までは問題なく出来るのであれば、その先はウィザードを使うの
    は諦めて、手作業でコードを書いて、それをウィザードで作った TableAdapter
    に合体させるという手段はいかがでしょう?

     

    もし必要でしたら例を書いてここにアップしますので連絡ください。

     

    > SurferOnWwwさんはその方法でうまく出来るんですよね?やっぱり他に原因があるんですかね・・・。

     

    自分の場合は SQL と OLE DB のみでしか試しておらず、しかもその両方とも
    Microsoft 製品なので問題ないのだと思います。

     

    401k さんの場合は DB 本体および DB と ADO.NET の間のドライバが他社製品
    ですよね? たぶん、それらとの相性の問題ではないかと思います。

    2008年5月21日 2:15
  • 手作業でコードを書いて、それをウィザードで作った TableAdapter に合体させる
    方法を連絡します。

     

    ただし、Firebird と ODBC ドライバをインストールして 401k さんと同様な環境
    で検証したわけではないということは、あらかじめご承知おきください。

     

    手順 (6) までは OK で、それで作った DataSet と TableAdapter がきちんと動い
    ているということが前提です。

     

    まず、手順 (6) で自動生成された「xsdファイル名.********.cs」の中を見てくだ
    さい。TableAdapter クラスの定義があるはずです。

     

    例えば、xsdファイル名が SampleDataSet、テーブル名が MAIL_USER だとすると、

    namespace SampleDataSetTableAdapters の中に、

    public partial class MAIL_USERTableAdapter というのが定義されているはずです。

     

    作業としては、App_Code フォルダにクラスファイルを一つ追加し、これに必要なク
    エリを含んだコードを、自動生成された TableAdapter と同じ partail クラスとし
    て記述することになります。

     

    OLE DB での例ですが、具体的には、xsdファイル名が SampleDataSet、テーブル名が
    MAIL_USER として、以下のようなコードになります。

     

    Code Snippet

    using System;
    using System.Data;
    using System.Configuration;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.HtmlControls;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;

     

    namespace SampleDataSetTableAdapters
    {
        public partial class MAIL_USERTableAdapter
        {
            [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Select)]
            public SampleDataSet.MAIL_USERDataTable GetDataByUsername(string username)
            {
                System.Data.OleDb.OleDbCommand cmd = new System.Data.OleDb.OleDbCommand();
                cmd.Connection = this.Connection;
                cmd.CommandText = "SELECT * FROM MAIL_USER WHERE USER_NAME = ?";
                cmd.CommandType = System.Data.CommandType.Text;
                System.Data.OleDb.OleDbDataAdapter da = new System.Data.OleDb.OleDbDataAdapter();
                da.SelectCommand = cmd;
                da.SelectCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter());
                if (username == null)
                {
                    da.SelectCommand.Parameters[0].Value = System.DBNull.Value;
                }
                else
                {
                    da.SelectCommand.Parameters[0].Value = username;
                }
                SampleDataSet.MAIL_USERDataTable dataTable = new SampleDataSet.MAIL_USERDataTable();
                da.Fill(dataTable);
                return dataTable;
            }
        }
    }

     

     

    2008年5月21日 9:49

すべての返信

  • 自動翻訳で日本語が変なんですが、以下のページが関連しそうです。

     

    データアダプタ構成ウィザードを使って、 OdbcDataAdapter を構成するとき、「マッピングが何も DbType オブジェクト から既知の OdbcType に存在しない」エラーが発生する A

    http://support.microsoft.com/kb/816802

     

    2008年5月14日 3:26
    モデレータ
  • trapemiyaさん、有用な情報ありがとうございます。

     

    あれからいろいろと調べてみたら、一般的にはODBC接続にはOdbcDataAdapterを使用するような感じになってるみたいなのですが、そもそもVWDExpressEditionではOdbcDataAdapterコントロールをツールボックスから使えるのでしょうか?

    ツールボックスのアイテム一覧の中には確かにOdbcDataAdapterコントロールはありますが、チェックを入れてもツールボックスに現れてくれません。

    基本的なことで申し訳ありませんが、よろしくお願いいたします。

    2008年5月16日 6:08
  •  401k さんからの引用

    ツールボックスのアイテム一覧の中には確かにOdbcDataAdapterコントロールはありますが、チェックを入れてもツールボックスに現れてくれません。

     

    VS2005の時からそうなってしまいました。

    ODBCではOdbcDataAdapterを使わなければならないというわけではなく、TableAdapterでパラメタライズドクエリも使えます。ただ、作成されたSQL文がおかしなことも稀にあるようなので、作成されたSQL文を確認された方が良いと思います。

    2008年5月16日 7:24
    モデレータ
  • App_Code フォルダを右クリック → [新しい項目の追加]をクリック → [データ
    セット]を選択 → 名前をつけて[追加]ボタンをクリック → ツールボックスから
    TableAdapter をドラッグ&ドロップ → ウィザードに従って DataSet と TableAdapter
    を作成されていると思いますが、そうであれば、

     

    C:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\[Webサイト名]\********\********\Sources_App_Code

     

    というフォルダーの中に、

     

    xsdファイル名.********.cs

     

    という名前のファイル(自動生成されたDataSet と TableAdapter)があるはずですの
    で、それを見てみてはいかがでしょう。

     

    自動生成さた TableAdapter の中には適切な DataAdapter がメンバーに含まれてい
    るのではないでしょうか(この場合は OdbcDataAdapter)?

     

    ちなみに、自分は VWD 2008 Express Edition をデフォルトで使っていますが、その
    ツールボックスには OdbcDataAdapter コントロールというのは見当たりません。です
    から、環境に違いがあって上記は外れているかもしれません。その場合は失礼しまし

    た。

    2008年5月17日 7:18
  •  trapemiya さんからの引用

    作成されたSQL文がおかしなことも稀にあるようなので、作成されたSQL文を確認された方が良いと思います。

     

    ご回答、ありがとうございます。

    簡単なSQL文をいろいろ試してみましたが、やはりエラーになります。

     

    SELECT ”取り出す列名” FROM ”テーブル名” WHERE ”条件列名” = ?

     

    ODBCドライバが何か悪さをしているようにも思われますので、そちらの方を調べてみます。

    2008年5月19日 4:49
  • SurferOnWwwさん、ご回答ありがとうございます。

     

    当該フォルダの********.csファイルの中身を覗いてみると、TableAdapterコンポーネントで設定したOdbcDataAdapterの記述がありました。残念ながら、ビルドに成功しないと********.csファイルが作成されないので、エラーが出ているSQLのどこが悪いのか見ることができませんが、TableAdapterの中でOdbcDataAdapterクラスやメンバがどのように記述されているのか理解することができました。

    しかしながら、私にはそれを自前で作成するスキルがありませんので、もう少し勉強したいと思います。また、他にODBCに対してのパラメータクエリをもっと簡単に作成できる方法やその資料があれば教えてください。

    よろしくお願いいたします。

    2008年5月20日 1:29
  •  401k さんからの引用

    簡単なSQL文をいろいろ試してみましたが、やはりエラーになります。

    SELECT ”取り出す列名” FROM ”テーブル名” WHERE ”条件列名” = ?

     

    まず、ウィザードで、条件なしで全アイテムを抽出する SELECT クエリを
    作ってから、TableAdapter に条件付 SELECT クエリを加えるようにしては
    いかがでしょう?

     

    手順は下記のようになります。

     

    (1) App_Code フォルダを右クリック
    (2) [新しい項目の追加]をクリック
    (3) [データセット]を選択
    (4) 名前をつけて[追加]ボタンをクリック
    (5) ツールボックスから TableAdapter をドラッグ&ドロップ

     

    (6) まず、条件なしで全アイテムを抽出する SELECT クエリを作成。
      手順は、TableAdapter 構成ウィザードに従って、
      ・データ接続の選択 → コマンドの種類を選択(SQL ステートメント
       を使用する) → SQL ステートメントの入力と進み、そこでクエリ
       ビルダで * にチェックを入れて条件なし全選択クエリを作成
      ・生成するメソッドの選択 → ウィザードの結果、と進んで正常に
       作成されたことを確認して完了。

     

    (7) 次に、TableAdapter に条件付 SELECT クエリを追加。
      手順は、

     (7-1) 表示されている TableAdapter の箱の中にツールボックスから
        Query をドラッグ&ドロップ

     (7-2) TableAdapter クエリの構成ウィザードに従って、
      ・コマンドの種類を選択 → クエリの種類の選択(複数行を返す
       SELECT) → SQL SELECT ステートメントの指定と進んで、クエリ
       ビルダ上で選択条件の列の「フィルタ」欄に =? と入力。出力しな
       い項目はチェックを外すなどしたあと、OK ボタンをクリックして
       SELECT クエリを作成
      ・生成するメソッドの選択 → ウィザードの結果、と進んで正常に
       作成されたことを確認して完了。

     

    これでもダメですと、あとは、手作業でコードを書いて、それをウィザ
    ードで作った TableAdapter(partial クラスとして定義されています)
    に合体させるぐらいしか方法は思いつきません。

     

    上記のようなことは言われなくても百も承知ということでしたら失礼し

    ました。

    2008年5月20日 2:43
  • すみません、間違えました。

     

    上のメッセージで (7-2) で「出力しない項目はチェックを外すなどしたあと」と書きま

    したが、チェックを外すと (6) で作成された DataTable と合わなくなってエラーにな

    ります。

    2008年5月20日 11:52
  • SurferOnWwwさん、ありがとうございます。

     

    私は初心者ですので参考書を見ながらですが、いろいろ試してみました^^;

    もう一度、SurferOnWwwさんの言われるやり方で試してみましたが、7-2で”=?”を入力後にクエリビルダ上でクエリ実行(クエリパラメータ入力)すればきちんと結果が表示するのですが、最後のウィザードの結果で「ウィザードでは、TableAdapterクエリ"FillBy1"を構成中に以下の問題が発生されました(詳細:DbType Objectから周知の・・・)」とエラーになります。

    他のテーブルに対しても行いましたが結果は同じでした。

     

    SurferOnWwwさんはその方法でうまく出来るんですよね?やっぱり他に原因があるんですかね・・・。

     

    2008年5月21日 0:34
  • クエリは正しいのに、何故かウィザードが正しくないと判断してエラーを出す
    ということのようですね。

     

    そうすると、ウィザードを使っての対応は、すみませんが自分としてはお手上
    げです。

     

    先の手順 (6) までは問題なく出来るのであれば、その先はウィザードを使うの
    は諦めて、手作業でコードを書いて、それをウィザードで作った TableAdapter
    に合体させるという手段はいかがでしょう?

     

    もし必要でしたら例を書いてここにアップしますので連絡ください。

     

    > SurferOnWwwさんはその方法でうまく出来るんですよね?やっぱり他に原因があるんですかね・・・。

     

    自分の場合は SQL と OLE DB のみでしか試しておらず、しかもその両方とも
    Microsoft 製品なので問題ないのだと思います。

     

    401k さんの場合は DB 本体および DB と ADO.NET の間のドライバが他社製品
    ですよね? たぶん、それらとの相性の問題ではないかと思います。

    2008年5月21日 2:15
  • 早速のご回答ありがとうございます。

     

    私が利用しているDBはFireBirdというオープンソースのちょっとマイナーなDBですが、パフォーマンスに優れ、管理もしやすい、なによりタダだということで利用しています。

    しかし、メジャーではないのでどうしても他の環境との相性がいまいちなところがあるようです。

     

    SurferOnWwwさん、よろしければ例をアップしていただけないでしょうか?

    よろしくお願いいたします。

     

    [使用環境]

    DBMS:Firebird SS 2.0.3
    ODBC Driver: IBPhoenix Firebird ODBC Driver v1.2.0 または v2.0.0

     

     

    2008年5月21日 3:11
  • 手作業でコードを書いて、それをウィザードで作った TableAdapter に合体させる
    方法を連絡します。

     

    ただし、Firebird と ODBC ドライバをインストールして 401k さんと同様な環境
    で検証したわけではないということは、あらかじめご承知おきください。

     

    手順 (6) までは OK で、それで作った DataSet と TableAdapter がきちんと動い
    ているということが前提です。

     

    まず、手順 (6) で自動生成された「xsdファイル名.********.cs」の中を見てくだ
    さい。TableAdapter クラスの定義があるはずです。

     

    例えば、xsdファイル名が SampleDataSet、テーブル名が MAIL_USER だとすると、

    namespace SampleDataSetTableAdapters の中に、

    public partial class MAIL_USERTableAdapter というのが定義されているはずです。

     

    作業としては、App_Code フォルダにクラスファイルを一つ追加し、これに必要なク
    エリを含んだコードを、自動生成された TableAdapter と同じ partail クラスとし
    て記述することになります。

     

    OLE DB での例ですが、具体的には、xsdファイル名が SampleDataSet、テーブル名が
    MAIL_USER として、以下のようなコードになります。

     

    Code Snippet

    using System;
    using System.Data;
    using System.Configuration;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.HtmlControls;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;

     

    namespace SampleDataSetTableAdapters
    {
        public partial class MAIL_USERTableAdapter
        {
            [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Select)]
            public SampleDataSet.MAIL_USERDataTable GetDataByUsername(string username)
            {
                System.Data.OleDb.OleDbCommand cmd = new System.Data.OleDb.OleDbCommand();
                cmd.Connection = this.Connection;
                cmd.CommandText = "SELECT * FROM MAIL_USER WHERE USER_NAME = ?";
                cmd.CommandType = System.Data.CommandType.Text;
                System.Data.OleDb.OleDbDataAdapter da = new System.Data.OleDb.OleDbDataAdapter();
                da.SelectCommand = cmd;
                da.SelectCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter());
                if (username == null)
                {
                    da.SelectCommand.Parameters[0].Value = System.DBNull.Value;
                }
                else
                {
                    da.SelectCommand.Parameters[0].Value = username;
                }
                SampleDataSet.MAIL_USERDataTable dataTable = new SampleDataSet.MAIL_USERDataTable();
                da.Fill(dataTable);
                return dataTable;
            }
        }
    }

     

     

    2008年5月21日 9:49
  • SurferOnWwwさん、お手数お掛けして申し訳ありません。

     

    ご丁寧なアドバイスありがとうございました。

     

    早速、試したいと思っておりますが、Visual Studio(C#)関連をまだあまり解ってないため、

    時間がかかると思いますが、がんばってやってみたいと思います。

     

    また、やってみた結果をアップしたいと思います。

    2008年5月22日 2:41