SQL文による抽出を使ってRecordsetをOpenしたいのですが。 – プログラミング – Home

SQL文による抽出を使ってRecord...
 
通知
すべてクリア

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


Takeshi
 Takeshi
(@Takeshi)
ゲスト
結合: 23年前
投稿: 83
Topic starter  

■動 作 環 境 :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水準
 第3水準
(@第3水準)
ゲスト
結合: 23年前
投稿: 17
 

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

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


返信引用
Takeshi
 Takeshi
(@Takeshi)
ゲスト
結合: 23年前
投稿: 83
Topic starter  

お世話になってます。

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

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

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

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


返信引用
ワルツ
 ワルツ
(@ワルツ)
ゲスト
結合: 23年前
投稿: 21
 

SQL文字列を通常に組み立てればいいでしょうね。

CString strSQL;

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

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

といった感じで。


返信引用
Takeshi
 Takeshi
(@Takeshi)
ゲスト
結合: 23年前
投稿: 83
Topic starter  

毎度、お世話になってます。

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

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


返信引用
第3水準
 第3水準
(@第3水準)
ゲスト
結合: 23年前
投稿: 17
 

>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水準
 第3水準
(@第3水準)
ゲスト
結合: 23年前
投稿: 17
 

上記のワイルドカード文字に関しては
文字列データのLIKE検索の場合は関係してきますが、
文字列データの = 検索の場合は関係なさそうです。
お騒がせしました。


返信引用
Takeshi
 Takeshi
(@Takeshi)
ゲスト
結合: 23年前
投稿: 83
Topic starter  

どうも、お世話になります。

具体的にこのような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水準
 第3水準
(@第3水準)
ゲスト
結合: 23年前
投稿: 17
 

>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
 Takeshi
(@Takeshi)
ゲスト
結合: 23年前
投稿: 83
Topic starter  

どうも、お世話になってます。

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

Takeshi


返信引用
Takeshi
 Takeshi
(@Takeshi)
ゲスト
結合: 23年前
投稿: 83
Topic starter  

解決のチェックを忘れていました。

以上


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました