OracleからOCCI(MSVC)への64ビット整数の読み取り

OCCI(Oracle C ++ Call Interface)は、OCI(Oracle Call Interface)上の非常に便利なオブジェクト指向シェルであり、Perlのような解釈プログラミング言語とほぼ同じ簡単さで、C ++からOracle DBMSに接続して作業することができます。 ただし、OCCIには欠点があります。 特に、Oracleの数値は、最大38桁の最大精度を提供するNumber型で表されますが、OCCIにはこの型を64ビット整数に変換する方法がありません。 通常の整数(32ビット)、倍精度(浮動小数点数、64ビット)、および長倍精度(浮動小数点数、80ビット(C標準による))に変換できますが、64ビット整数には変換できません。



doubleに変換してからlong longに変換するオプションは、多くのユーザーに適していますが、52ビットの精度(double型の格納された仮数のサイズは52ビット)を提供し、その結果、精度が低下する可能性があるため、すべてではありません大きな数字で。 long doubleへの中間変換で問題を解決できるように見えますが、Microsoftコンパイラの制限がここで作用します-80ビット浮動小数点数をサポートせず、long double型をdouble型の類似物として受け入れます。



同時に、OCCIの基礎となるOCIはNumberからlong longへの変換を実行できます。 このため、次の機能があります。



sword OCINumberToInt (OCIError *err, const OCINumber *number, uword rsl_length, uword rsl_flag, void *rsl);
      
      





この関数は、パラメータに、初期数値const OCINumber * number 、結果の数値void * rslへのポインタ 、および結果の数値(バイト単位) uword rsl_lengthのポインタを取ります。 サポートされている結果サイズには8があります。 64ビット。 あとは、OCINumberを取得するだけです。



残念ながら、ここでは次の問題に直面しています-ResultSetからのOCCI(クエリの結果であるクラス)では、OCINumberを取得することもできません。また、OCINumberのラッパーであるoracle :: occi :: Numberクラスもそのアクセスを提供しません内臓をプライベートと宣言して:



 private: /* Private constructor for constructing number from methods inside */ OCINumber getOCINumber() const; OCINumber data;
      
      





そしてここで、C ++で完全に異なる型を相互に変換する可能性を支援します。 Numberクラスには仮想メソッドがなく、 OCINumberデータメンバーがクラスの最初であるため、メモリ内のこのメンバーのアドレスはクラスインスタンスのアドレスと一致します。 つまり 書くだけで十分です。



 oracle::occi::Number number; OCINumber *ociNumber = (OCINumber*)&number;
      
      





その結果、Numberを64ビット整数に変換する機能(MSVCの場合)は次のとおりです。



 __int64 OCCINumberToInt64 (const oracle::occi::Number &number, OCIError *hError, bool bSigned) { const OCINumber *ociNumber = (const OCINumber*)&number; __int64 result; OCINumberToInt (hError, ociNumber, 8, bSigned ? OCI_NUMBER_SIGNED : OCI_NUMBER_UNSIGNED, &result); return result; }
      
      





また、必要なOCIエラーハンドル関数を取得するには、次のコードを使用できます。



 oracle::occi::Environment env; ... OCIEnv *hEnv = env->getOCIEnvironment (); OCIError *hError = 0; OCIHandleAlloc (hEnv, (void**)&hError, OCI_HTYPE_ERROR, 0, 0); ... OCIHandleFree (hError, OCI_HTYPE_ERROR);
      
      






All Articles