トップ回答者
TableAdapterにおけるODBCデータベースへのパラメタライズドクエリについて

質問
-
ASP .NETの初心者です。
今まではボーランド系の開発ツールを使用してWindowsアプリを作成していましたが、現在はWebアプリを作成しながら.NET Frameworkについて勉強しています。
そういう中で分からないところが出てきましたので、お助けください。
VWD2008のTableAdapterを使用してODBCで繋げたデータベースとの接続をデータアクセスコンポーネントを使用してウィザードに従い作成しています。
パラメータのないSELECTについては問題なくデータを取り出すことが出来たのですが、パラメータを設定したクエリを作成した場合はウィザードの最後に、「DbType Object から周知の型 OdbcType へのマッピングは存在しません」と表示されます。無理やりウィザード完了させると、テーブルアダプタにクエリは作成されるのですが、もちろんデバッグするとエラーになります。しかし、後から作成されたクエリのプロパティからクエリビルダを開き、それを実行させると正常に動作します。
テーブルアダプタ内のSQL分は以下のような記述です。
SELECT MAIL_ADD FROM MAIL_USER WHERE USER_NAME = ?
OdbcDataAdapter クラスというのがありますが、そちらを使うべきなのかもよくわかりません。
少し初歩的な質問かも知れませんが、よろしくお願いいたします。
回答
-
自動翻訳で日本語が変なんですが、以下のページが関連しそうです。
データアダプタ構成ウィザードを使って、 OdbcDataAdapter を構成するとき、「マッピングが何も DbType オブジェクト から既知の OdbcType に存在しない」エラーが発生する A
http://support.microsoft.com/kb/816802
-
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 コントロールというのは見当たりません。です
から、環境に違いがあって上記は外れているかもしれません。その場合は失礼しました。
-
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 クラスとして定義されています)
に合体させるぐらいしか方法は思いつきません。上記のようなことは言われなくても百も承知ということでしたら失礼し
ました。
-
クエリは正しいのに、何故かウィザードが正しくないと判断してエラーを出す
ということのようですね。そうすると、ウィザードを使っての対応は、すみませんが自分としてはお手上
げです。先の手順 (6) までは問題なく出来るのであれば、その先はウィザードを使うの
は諦めて、手作業でコードを書いて、それをウィザードで作った TableAdapter
に合体させるという手段はいかがでしょう?もし必要でしたら例を書いてここにアップしますので連絡ください。
> SurferOnWwwさんはその方法でうまく出来るんですよね?やっぱり他に原因があるんですかね・・・。
自分の場合は SQL と OLE DB のみでしか試しておらず、しかもその両方とも
Microsoft 製品なので問題ないのだと思います。401k さんの場合は DB 本体および DB と ADO.NET の間のドライバが他社製品
ですよね? たぶん、それらとの相性の問題ではないかと思います。 -
手作業でコードを書いて、それをウィザードで作った 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 Snippetusing 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;
}
}
}
すべての返信
-
自動翻訳で日本語が変なんですが、以下のページが関連しそうです。
データアダプタ構成ウィザードを使って、 OdbcDataAdapter を構成するとき、「マッピングが何も DbType オブジェクト から既知の OdbcType に存在しない」エラーが発生する A
http://support.microsoft.com/kb/816802
-
-
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 コントロールというのは見当たりません。です
から、環境に違いがあって上記は外れているかもしれません。その場合は失礼しました。
-
SurferOnWwwさん、ご回答ありがとうございます。
当該フォルダの********.csファイルの中身を覗いてみると、TableAdapterコンポーネントで設定したOdbcDataAdapterの記述がありました。残念ながら、ビルドに成功しないと********.csファイルが作成されないので、エラーが出ているSQLのどこが悪いのか見ることができませんが、TableAdapterの中でOdbcDataAdapterクラスやメンバがどのように記述されているのか理解することができました。
しかしながら、私にはそれを自前で作成するスキルがありませんので、もう少し勉強したいと思います。また、他にODBCに対してのパラメータクエリをもっと簡単に作成できる方法やその資料があれば教えてください。
よろしくお願いいたします。
-
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 クラスとして定義されています)
に合体させるぐらいしか方法は思いつきません。上記のようなことは言われなくても百も承知ということでしたら失礼し
ました。
-
SurferOnWwwさん、ありがとうございます。
私は初心者ですので参考書を見ながらですが、いろいろ試してみました^^;
もう一度、SurferOnWwwさんの言われるやり方で試してみましたが、7-2で”=?”を入力後にクエリビルダ上でクエリ実行(クエリパラメータ入力)すればきちんと結果が表示するのですが、最後のウィザードの結果で「ウィザードでは、TableAdapterクエリ"FillBy1"を構成中に以下の問題が発生されました(詳細:DbType Objectから周知の・・・)」とエラーになります。
他のテーブルに対しても行いましたが結果は同じでした。
SurferOnWwwさんはその方法でうまく出来るんですよね?やっぱり他に原因があるんですかね・・・。
-
クエリは正しいのに、何故かウィザードが正しくないと判断してエラーを出す
ということのようですね。そうすると、ウィザードを使っての対応は、すみませんが自分としてはお手上
げです。先の手順 (6) までは問題なく出来るのであれば、その先はウィザードを使うの
は諦めて、手作業でコードを書いて、それをウィザードで作った TableAdapter
に合体させるという手段はいかがでしょう?もし必要でしたら例を書いてここにアップしますので連絡ください。
> SurferOnWwwさんはその方法でうまく出来るんですよね?やっぱり他に原因があるんですかね・・・。
自分の場合は SQL と OLE DB のみでしか試しておらず、しかもその両方とも
Microsoft 製品なので問題ないのだと思います。401k さんの場合は DB 本体および DB と ADO.NET の間のドライバが他社製品
ですよね? たぶん、それらとの相性の問題ではないかと思います。 -
早速のご回答ありがとうございます。
私が利用しているDBはFireBirdというオープンソースのちょっとマイナーなDBですが、パフォーマンスに優れ、管理もしやすい、なによりタダだということで利用しています。
しかし、メジャーではないのでどうしても他の環境との相性がいまいちなところがあるようです。
SurferOnWwwさん、よろしければ例をアップしていただけないでしょうか?
よろしくお願いいたします。
[使用環境]
DBMS:Firebird SS 2.0.3
ODBC Driver: IBPhoenix Firebird ODBC Driver v1.2.0 または v2.0.0 -
手作業でコードを書いて、それをウィザードで作った 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 Snippetusing 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;
}
}
}