!!!Oracle Pro*C/C++ {{category Oracle,nolink}}Pro*C/C++ は、Oracle Database において C言語の埋め込みSQLを実現するためのプリコンパイラです。ANSIなどで規定されている埋め込みSQLと互換があるので他のDB用の移行は比較的簡単にできる(はず)。 !!!DataBase と C のデータ型関係 基本的には変換可能なデータであればOracleが面倒みてくれます。 ""暗黙の型変換が行われて遅くなると言われればそうなんですが、DBとCとの間で行われているだろうから同じ気もしないでもない…。DATEやNUMBER型はOracle独自の形式だと思うのですが。(未検証です) !!Oracle:CHAR - WHERE句で比較 SQLでCHAR項目を比較する際に、桁数に満たない場合は自動的に空白が追加された状態で比較されます。 WHERE句でホスト変数から条件を指定したときに、C:charの場合は、SQLと同様に空白が付与されますが、C:varcharの場合は、空白が付与されないため不一致になる。 !!C:char* - INTO句からの取得 INTO句でcharポインタのホスト変数にセットする場合3バイト分(Windows系)しかセットされない。WHERE句等で値を渡す場合は問題ない。 //// オプション(char_map)追加のため統一 //// //!!C:char INTO句からNULL値の取得 //INTO句でcharのホスト変数にセットする場合、確保したバイト数-1のサイズまで、空白が付与されてセットされる。SET句等値を渡す場合は問題ない。 // //!!Oracle:CHAR,VARCHAR ⇒ C:char //デフォルト時(char_map=CHARZ) //項目値を取得するときに、確保したバイト数-1のサイズまで、空白が付与されてセットされる。 !!Oracle:CHAR,VARCHAR ⇒ C:char オプション(char_map)の設定による。 ,データ型,固定/可変 ,NULL終端,DBのNULL時 ,VARCHAR2,固定長(*1),なし,空白セット ,STRING ,可変長 ,あり,先頭NULL止 ,CHARF ,固定長(*1),なし,セット無し(*2) ,CHARZ ,固定長(*1),あり,空白セット (注) ※1:確保した配列のバイト数(NULL終端がある場合はサイズ-1)まで、空白が付与される。 ※2:DBがNULLの場合、何もしないため、直前にセットされていた値がそのまま残る。 !!Oracle:DATE TO_DATE,TO_CHAR,TO_NUMBERをして、明示的に型変換して行うのが環境に悩まされたりしなくて良いと思います。 !⇔ C:char,C:varchar デフォルトの日付書式で型変換される。 !⇔ C:long,C:double ''プログラマーズ・ガイドにはC:long型にはもセット可能とありますが、どういう形でセットされるか不明です。'' !!Oracle:NUMBER ⇒ C:long(32bit int) 型の有効範囲の関係でNUMBER(9)までは可能。10桁以上(正確には、±31~2)の数値の場合エラーになる。 !!C:long long int (64bit int) 使えるんでしょうか? !!!SQL ERROR CODE !!ORA-01002: フェッチ順序が無効です。 :原因:ホスト言語プログラムのFETCH コールの発行順序が誤っています。フェッチの前にPARSE およびEXECUTE コールが正常に発行される必要があります。すべてのレコードのフェッチ後に、アクティブ・セットからFETCH を実行しようとすると、このエラーが発生する場合があります。または、コミット後のSELECT FOR UPDATE カーソルからのフェッチによってエラーが発生する場合もあります。また、PL/SQL カーソル・ループが暗黙にフェッチを行うとエラーの原因となる場合もあります。 :処置:データをフェッチする前に、SQL 文を解析して実行してください。 *Open, Fetch の順序あってる? *FOR UPDATE を使っていない? *MODE=ANSI で Fetch中に commit/rollback になっていない? *Record Not Found(ORA-1403)が返ってきた後に更に、Fetch していないか? !!ORA-01480: STRバインド値に終了のNULLがありません。 :原因:char型のホスト変数で実際に確保されている配列サイズを超えてセットされている。確保した配列サイズ内でNULL留めになっていない。 :処置:変数のサイズを気を付けましょう !!ORA-01555 スナップショットが古すぎます... :原因:一貫した読込みに必要なロールバック・レコードが他のユーザーによって上書きされています。 :処置:自動UNDO管理モードを使用している場合は、UNDO_RETENTION の設定値を増やしてください。使用していない場合は、さらに大きいロールバック・セグメントを使用してください。 +検索と更新を同時に実行しないようにアプリケーションを見直す +コミットを行わない、もしくはコミットの回数を減らしてUNDOブロックが上書きされる可能性を下げる +UNDOブロックが上書きされるのを防ぐ **Oracle9i 以降で UNDO_MANAGEMENT=AUTOの場合 ***初期化パラメータ UNDO_RETENTION の値を増やす ***UNDO表領域のサイズを増やす **Oracle8i 以前、UNDO_MANAGEMENT=FALSE の場合 ***RBSの数、サイズを増やす ***大き目のRBSをあらかじめ用意しておき、TRAN:Bに明示的にその大きなRBSを割り当てる (SET TRANSACTION ROLLBACK SEGMENT ... を使用) ***OPTIMALが設定してある場合、その設定を大きくする !!!Pro*C/C++ 備忘録 !!Pro*C/C++ の制限事項 Pro*C/C++ を使用する中でいくつか制限事項がある(Pro*C/C++のバグというか、構文解析が、OracleのSQL構文に追いついていないように思われる)。※9iで確認 :: CASE という項目名 :::取得する項目名にCASEと言う項目名が存在すると、SQLCHEK=FULL等で構文解析を行うと、CASE式に間違われるらしくエラーとなる。 ::SELECT句内での副問い合せ :::構文エラーとなる。FROM句に書く場合はエラーにならない。 ::分析関数の使用 :::使用できない。Pro*Cに構文解析させなければ利用可能。 PCC-S-02201, 記号"("が見つかりました。 次のうちの1つが入るとき: PCC-F-02102, Cプリプロセッサ処理を実行中に致命エラーが発生しました。 ::MERGE構文 :::使用できない。Pro*Cに構文解析させなければ利用可能。 PCC-S-02201, 記号"MERGE"が見つかりました。 次のうちの1つが入るとき: PCC-S-02206, DDL文で、ホスト変数は使用できません。 !!Oracle9i Pro*C/C++ GIU版 オプションダイアログが出ない ::現象 :::Oracle9i に付属する procui.exe を立ち上げソースファイルと選択し、オプションを設定しようとダブルクリックすると「ANSI」というエラーMSGダイアログボックスが4回表示され、オプション画面が立ち上がらない。 ::解決策 :::%ORACLE_HOME%\BIN\procja9.dllをリネームして、もしくは、レジストリを修正し、英語モードで起動させる。 ::情報源 :::日本語版のバグだそうです。 *[OTN FAQ No.29112|http://support.oracle.co.jp/open/owa/external_krown.search_doc?c_document_id=29112] *[OTN FQA No.30014|http://support.oracle.co.jp/open/owa/external_krown.search_doc?c_document_id=30014] !!Oracle10g GIU版のショートカットがメニューに登録されない Oracle10gからは、Pro*C/C++は、CUIのみの提供となる ::情報源 *[@IT 会議室 |http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=22912&forum=26]