はじめまして,C++でのDB操作でかなりてこずってます.
現在,VC++でMFCでODBCを使用してSQLserverに接続しています.
SQLServerに接続は問題なく出来るのですが
データ入力のところで以下ような問題に悩んでいます.
SQLCHAR szCommand[255] =
(INSERT INTO DBNAME (%s) VALUES (%d),name,data);
name:char型 data:short型
となっており,実行すると.
error C2440: '初期化中' : 'short' から 'SQLCHAR [255]' に変換できません。
といったエラーが表示されます.
このエラーを解決するにはどのようにすればいいのでしょうか??
1行目でC++と書いてしまいましたが,VC++の間違いでした.すいません.
バージョンはいったい何なのでしょう?
VS2005以降だったりするとデフォルトの文字コードが
UNICODEになっているのでデフォルトの文字列はWCHARだったりしたと
思いますけれど。
とりあえず文字列の初期化の方法が間違ってます。
書式指定で文字列を作るなら普通は
sprintf_s/wsprintfなどを使います。
そしてSQLインジェクション脆弱性を作りこむ、と。
今のうちからよく検討しておいたほうがいいよ
>PATIOさん
バージョンは2005です.
えっと,VSのデフォルトがUNICODEで,SQLのデフォルトがWCHARAということでしょう
か?
>subaruさん
sprintf(szCommand,~);
みたいな感じでしょうか?
~のところで上記のSQLの内容を書いてしまえばいいんですね?
>tetrapodさん
えっと・・・SQLインジェクション脆弱性というのがよくわからないのですが
具体的にどのようなものなのでしょうか?
>SQLCHAR szCommand[255] =
>(INSERT INTO DBNAME (%s) VALUES (%d),name,data);
入門書読み直した方が良いよ?
エラーの意味だけは教えておきます。
以下の部分、
INSERT INTO DBNAME (%s) VALUES (%d),name,data
カンマ演算子で、
INSERT INTO DBNAME (%s) VALUES (%d)
name
data
の空処理とみなされているだけです。
で、最後の data が =演算子の戻り値として採用されています。
というわけで、エラーメッセージと合っているでしょ。
その先は、少し自分で考えてみてくださいな。
暑いので殺伐としてますね。
>sprintf(szCommand,~);
>みたいな感じでしょうか?
>~のところで上記のSQLの内容を書いてしまえばいいんですね?
です。確認するより、まずは実行あるのみです。
>SQLインジェクション
http://ja.wikipedia.org/wiki/SQL%E3%82%A4%E3%83%B3%E3%82%B8%E3%82%A7%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3
sprintf_sについても検索してみるといいかもしれません。
いろいろと情報ありがとうございます.
sprintf_sを使用し,以下のソースで実行してみました.
SQLCHAR szCommand[255];
sprintf_s(szCommand, 255,INSERT INTO airpenDB ('%s') VALUES (%d),recog_item
[i].item_name,recog_item[i].result);
すると
int sprintf_s(char *,size_t,const char *,...)' : 1 番目の引数を 'SQLCHAR
[255]' から 'char *' に変換できません。
というエラーが発生しました.
そこで
char szCommand[255];
変更し実行してみましたが,
後で書かれている
retcode = SQLExecDirect(hstmt1,szCommand,SQL_NTS);
のところで「2 番目の引数を 'char [255]' から 'SQLCHAR *' に変換できません。」
というエラーが表示されました.
char,SQLCHAR等の型をうまく合わせる方法ってなにかありますでしょうか??
自分でも色々と調べてみているのですが,良い方法がなかなか見つからないので….
よろしくお願いします.
SQLCHARはunsigned char配列なのでキャストするしかないのでは?
SQLTCHARという型もあるようだけど使えないのかな?
MFCなのでこんな感じでも動くと思います。
CStringA sql;
sql.Format(INSERT INTO airpenDB ('%s') VALUES (%d),recog_item
[i].item_name,recog_item[i].result);
retcode = SQLExecDirect(hstmt1,(SQLCHAR*)(LPCSTR)sql,SQL_NTS);
ODBC APIは触ったことないけどSQLインジェクションに対策するなら
SQLBindParameterあたりを使うんじゃないだろうか。
> ODBC APIは触ったことないけどSQLインジェクションに対策するなら
> SQLBindParameterあたりを使うんじゃないだろうか。
「SQLBindCol」で変数をセットします。
必要に応じてキャストします。
ODBC APIは、SQL_C_????等の型があるので合うのを選定しないといけないですね。
2005で確認できないのでなんですが
そんなめんどくさい型ならあえて使わなくても
いいんではないかと。
WCHAR szCommand[255];
SQLCHARって
bcp用の変数の型ですね。
SQLserver用のツ-ルの変数の型で、VC++ようの変数の型ではないですね。
まず
1. やり取りを行うデータテ-ブル変数の型を調べる。
2. 使うVC++のODBCの関数を特定する。
MFC?、ODBC API?、ADO?
3. VC++のODBCの関数に合う変数の型を調べる。
MFCとなるとCRecordset,Database ですね。
MSDN CDの「ODBCの基礎」をよく読みましょう。
ADOは、資料は少ないですがここの過去ログにあると思います。
一番大事なことは、「データ型はSQLserverに合わせる。」ということです。
ん?
SQL文を作って保存するだけならわざわざSQLCHAR使わなくてもいいんじゃないですか?
CRecordset,Database ならLPCTSTRなんでchar型でいいんじゃないですか。