SQL文による抽出を使ってRecordsetをOpenしたいのですが。

[戻る]
Takeshi 2002/05/01(水) 20:02:17
■動 作 環 境 :Windows2000
■開 発 環 境 :Visual C++6.0(MFC使用,ODBC接続)
■データベース:Access2000


  お世話になります。
レコードセットをオープンする時に、引数にSQL文を渡して抽出しようとしています。
現在のコードは以下の通りです。

前提として、複数の Field を持つ Table1 があるとします。

MyRecordset.Open
(CRecordset::snapshot,"select * from Table1 where Field1 = CString1 or 
Field2 = CString1",CRecordset::readOnly);

Table1 の全フィールドから、Field1またはField2が、指定した文字列と同じレコードだけを
抽出してオープンしたいのです。

ですが、実行すると「パラメータが少な過ぎます。2を指定して下さい。」という
メッセージが表示されて、レコードセットがオープンできません。
SQL文による抽出をしなければレコードセットをオープンできるのですが、
それでは仕様を実現できないのです。

引数に渡した SQL文 に誤りがあるのでしょうか?
アドバイスをお願いできますでしょうか?

第3水準 2002/05/02(木) 09:45:23
「Field1かField2のデータが CString1と言うCString型変数の中身に等しいレコード」
では無く
「Field1かField2のデータが"CString1"と言う文字列に等しい」レコード
をSELECTするんですよね?
その場合、CString1を['](半角シングルクォート)で囲んでみたらどうでしょうか?
具体的にはこんな感じのSQL文になります

select * from Table1 where Field1 = 'CString1' or Field2 = 'CString1'

Takeshi 2002/05/02(木) 09:57:50
  お世話になってます。


すいません、誤解があったようです。

欲しいのは Field1 か Field2 のデータが CString1 と言うCString型変数の中身に等しい
レコード なんです。

ですから、この CString1 は毎回変動の可能性がある文字列です。


  それと、「パラメータが少な過ぎる」という警告は具体的に何を指しているのですか?
どこの何のパラメータが足りないのかすら分からないのですが・・・。
警告メッセージが貧弱過ぎるような気がします。

ワルツ 2002/05/02(木) 10:15:38
SQL文字列を通常に組み立てればいいでしょうね。

CString strSQL;

strSQL = "select * from Table1 where Field1='";
strSQL += CString1;
strSQL += "'";

MyRecordset.Open
(CRecordset::snapshot, strSQL, CRecordset::readOnly);

といった感じで。

Takeshi 2002/05/02(木) 10:29:56
  毎度、お世話になってます。

という事は、「パラメータが少ない」という警告に対しては
SQL文を直接書き込むのではなく、CString型に入れてから使ったら
解決できるという事ですね?

分かりました、やってみます。ありがとうございました。

第3水準 2002/05/02(木) 11:04:13
>SQL文字列を通常に組み立てればいいでしょうね。
>
>CString strSQL;
>
>strSQL = "select * from Table1 where Field1='";
>strSQL += CString1;
>strSQL += "'";
>
>MyRecordset.Open
>(CRecordset::snapshot, strSQL, CRecordset::readOnly);
>
>といった感じで。
細かい所ですが気になったので、
CString1内に[']がある場合は[']を重ねる必要があります。

CString1.Replace("'","''");

で変換できると思います。

あと、ACCESS2000の場合、ワイルドカード文字があるので
これも変換する必要があるかもしれません。
ワイルドカード文字に関しては
ACCESS2000のヘルプで
[データの検索および並べ替え]
 →[データの検索および置換]
  →[値を検索するためのワイルドカード文字の使用について]
に詳しく書いてあります。

第3水準 2002/05/02(木) 11:33:22
上記のワイルドカード文字に関しては
文字列データのLIKE検索の場合は関係してきますが、
文字列データの = 検索の場合は関係なさそうです。
お騒がせしました。

Takeshi 2002/05/02(木) 11:46:43
  どうも、お世話になります。

具体的にこのようなSQL文字列を作成して、CRecoedsetに渡してOpenしています。

CString MyString;            /* 文字列型オブジェクト */

CString SQL_CS;              /* 文字列型オブジェクト */

MyString = "ダミーのデータ";  /* この文字列は変動します */

SQL_CS = "SELECT * FROM MyTable WHERE Field1 = MyString OR Field2 = MyString";

MyRecordset.Open(CRecordset::snapshot,SQL_CS,CRecordset::readOnly);


実行結果は「パラメータが少な過ぎます。1を指定して下さい。」の警告でした。
この 1 を指定とはどういう事ですか?

WHERE 以降を書かなければこういう警告は出ないのです。
このSQLに問題があるのでしょうか?

第3水準 2002/05/02(木) 12:01:25
>WHERE 以降を書かなければこういう警告は出ないのです。
>このSQLに問題があるのでしょうか?
SQL文字列の中に、VC++の変数を変数名を指定して直接含めることは出来ません。
また、SQLの書式上、文字列データは[']で囲んでやる必要があります。

そのため、SQL文字列に変数の中身を反映させる場合は
SQL文字列を動的に生成する必要があります。

上記の場合

SQL_CS.Format("SELECT * FROM MyTable WHERE Field1 = '%s' "
  "OR Field2 = '%s' ",
  (LPCTSTR)MyString,(LPCTSTR)MyString);

としてやれば、
SQL文字列が

SELECT * FROM MyTable WHERE Field1 = 'ダミーのデータ' OR Field2 = 'ダミーのデータ
'
と動的に生成されます。

Takeshi 2002/05/02(木) 12:27:47
  どうも、お世話になってます。

うまくいきました、ありがとうございます。
第3水準さんはこういう知識をどこから勉強されたのですか?
SQL関係の書籍ですか?宜しかったら教えてください。

                         Takeshi

Takeshi 2002/05/02(木) 12:28:23
[[解決]]
解決のチェックを忘れていました。

                 以上

古いスレッドには追加発言できません。