CRecordsetクラスのGetFieldValueを利用してデータを取得しようしているのですが、取
得時のフィールドの型がNVARCHA2のためか、データがかけて取得されます。
そのカラムのサイズは、11なのですが、NVARCHA2は文字数がサイズとなるため、半角文
字だと11Byteなのですが、全角文字だと33Byte格納できます。(UTF-8の場合)
しかし、GetFieldValueを利用すると11Btye分しかデータを取得できないようなのです。
フィールドの型がNVARCHA2を取得する際には、どうしたらよいかご存知の方おられまし
たら教えてください。
ちなみに環境は、visiual stadio C++ 6.0を使用しています。
データベースは、oracle 10gです。
CRecordsetでMFCの話だと
http://msdn.microsoft.com/ja-jp/library/5f8k59f9(VS.80).aspx
GetFieldValueの、nFieldTypeにわざと何か変なオプションを
つけているとかはないですか?
3番目の
void GetFieldValue(
short nIndex,
CStringA& strValue
);
でも駄目ですか?
後は
tsuka-さんはどのようにして半分と言う事を確かめたのでしょうか。
私の認識だと
CString buf;
m_db.OpenEx(DSN=hoge~);
CRecordset rset(&m_db);
rset.Open( AFX_DB_USE_DEFAULT_TYPE,SELECT * hoge FROM hoge);
rset_head.GetFieldValue(1,buf);
もしくは
rset_head.GetFieldValue(hoge,buf);
可能であれば再現できるソースをアップしていただいたほうが早道だと思います。
とりさんコメントありがとうございます。
ソースとDBの構成をアップします。
以下のcを取得するときに11Byteより多い文字の時に現象がデータがかけて取得される
という現象が発生します。
もし、お気づきの点等ありましたら、よろしくお願いします。
■ソース
CString strValue=";
short Count;
CString strSql=SELECT a,b,c FROM dbname;
CDatabase db;
db.OpenEx(DSN=hoge~);
CRecordset rs( &db );
rs.Open( CRecordset::forwardOnly, _T( strSql ) );
nFields = rs.GetODBCFieldCount();
int line = 0;
while( !rs.IsEOF() )
{
for(Count=0 ; Count < nFields ; Count++) {
// データの取得(ONE)
rs.GetFieldValue( Count, _T( strValue ) );
m_ctlFGrid.SetTextArray(GenID(line+1,Count), strValue );
}
UpdateData(FALSE);
rs.MoveNext();
line++;
}
rs.Close();
db.Close();
■db構造
desc dbname
名前 NULL? 型
----- -------- ----------------------------
a NOT NULL NUMBER(2)
b VARCHAR2(11)
c NVARCHAR2(11)
とりあえず、間違っている点
>rs.Open( CRecordset::forwardOnly, _T( strSql ) );
>rs.GetFieldValue( Count, _T( strValue ) );
変数に_Tマクロを使うのはおかしい。
_Tマクロはxxxxのような文字(列)定数に使うものです。
Unicodeビルドしたとき、コンパイルエラーになるでしょう。
本題ですが、CDBVariantを引数にとるGetFieldValueではどうでしょうか?
また、MBCSでコンパイルしているようですが、UTF-8の文字列がCP932(Shift_JIS)で表現
しきれないのは大丈夫でしょうか?
Blueさんコメントありがとうございます。
>変数に_Tマクロを使うのはおかしい。
>_Tマクロはxxxxのような文字(列)定数に使うものです。
>Unicodeビルドしたとき、コンパイルエラーになるでしょう。
_Tマクロについては、理解不足でした。
よく分からず、前の人のサンプルソースをそのまま使っていたので、間違いを疑いませ
んでした。
>本題ですが、CDBVariantを引数にとるGetFieldValueではどうでしょうか?
CDBVariantの中のデータメンバの中には、NVARCHAR2に対応したメンバが存在しないよう
です。実行するとプログラムがダウンしてしまいました。
>また、MBCSでコンパイルしているようですが、UTF-8の文字列がCP932(Shift_JIS)で
>表現しきれないのは大丈夫でしょうか?
海外対応のパッケージソフトの一部のDBを利用したツールを作成しています。
このツールは、海外対応する必要のないツールのため、文字コードは、S_JISで扱う予定
でいますので、あまり深く考えていないですね。
なんかキャラクタ・セマンティクスの(N)VARCHAR(2)はサポート外のような希ガス。。。
http://support.microsoft.com/kb/239719/ja
この辺でしょうか?
http://support.microsoft.com/kb/249803/ja
こんな感じで回避できないでしょうか?
#機械翻訳なのでなんだかよく分かりませんけど。
Oracleの提供しているODBCドライバを使っても
同じ現象になりますか?
Bule さん とり さん コメントありがとうございます。
>Oracleの提供しているODBCドライバを使っても
>同じ現象になりますか?
oracleのドライバーでは、同現象が発生しました。
マイクロソフトが提供しているoracleのドライバー(Microsoft ODBC for Oracle)
に変更したらうまくいきました。
でも、出来ればoracleのドライバーで行いたいと思っています。
(既存のシステムは、oracleのドライバーのため)
やはりODBC以外の方法を検討した方が、いいのでしょうか??
> でも、出来ればoracleのドライバーで行いたいと思っています。
> やはりODBC以外の方法を検討した方が、いいのでしょうか??
Oracle純正にこだわるなら、OO4Oがお勧めです。
C++のクラスライブラリにも対応してるので使いやすいです。
このサンプルが分かりやすいかな。
http://yamadila.at.infoseek.co.jp/pgdiary/20041015vcoo4o.html
たぶん、何の説明もなく理解できると思います。
bun さんコメントありがとうございます。
長い間放置してすみません。。
bunさんに勧めて頂いた方法で解決させました。
僕のバグでなく、ドライバーのバグだと分かるまでにかなり工数を使用してしまいまし
た。
色々なDBアクセス方法を学んどかないといけないみたいですね。
少し、反省です。
多くの方にコメントいただきありがとうございました。
> bunさんに勧めて頂いた方法で解決させました。
> 僕のバグでなく、ドライバーのバグだと分かるまでにかなり工数を使用して
> しまいました。
解決してますが、
今回oracleのドライバーのバグみたいですが、oracleとwindows、特に「sqlサーバ」
と「アクセス」のドライバのSQL文の文法に微妙な食い違いがあります。
バグでなくてもうまくいかないことが多いです。
僕もSQL文の食い違いに悩みました。
#たぶんoracle側があっていると思う。
oracleを使い慣れている方でしたら、見当違いでしたね。
たぶんoracle側の担当者が知っていると思うので打ち合わせしてみるといい
と思います。