24 Oracle ODBC Driverの使用方法

この章の構成は、次のとおりです。

トピック:

Oracle ODBC Driverについて

ODBCとは

Open Database Connectivity (ODBC)は、1つのアプリケーションが多くの異なるデータソースにアクセスできるようにする標準インタフェースを提供します。アプリケーションのソース・コードをデータ・ソースごとにコンパイルしなおす必要はありません。データベース・ドライバにより、アプリケーションが特定のデータ・ソースにリンクされます。データベース・ドライバは、アプリケーションが特定のデータソースにアクセスするためにオンデマンドで呼び出すことのできるダイナミック・リンク・ライブラリです。したがって、アプリケーションはデータベース・ドライバが存在するすべてのデータ・ソースにアクセスできます。

ODBCインタフェースには次のものが定義されています。

  • ODBC関数コールのライブラリ。アプリケーションではこのライブラリを利用してデータソースに接続し、構造化問合せ言語(SQL)文を実行して結果を取り出すことができます。

  • SQL-99仕様に基づくSQL構文

  • エラー・コードの標準セット

  • データソースへの接続とログインの標準的な方法

  • データ型の標準的な表現

次の図に、ODBCモデルのコンポーネントを示します。モデルは、ODBCアプリケーションがODBCアプリケーション・プログラム・インタフェース(API)を介してドライバ・マネージャをコールするところから始まります。ドライバ・マネージャは、Microsoftドライバ・マネージャまたはunixODBCドライバ・マネージャです。ドライバ・マネージャは、ここでもODBC APIを使用してODBCドライバをコールします。ODBCドライバは、データベースAPIを使用し、ネットワーク通信リンク経由でデータベースにアクセスします。次の図に、異なる3つのデータベースにアクセスするODBCアプリケーションを示します。

図24-1 ODBCモデルのコンポーネント

図24-1の説明が続きます
「図24-1 ODBCモデルのコンポーネント」の説明

関連トピック

すべてのユーザー

トピック:

Oracle ODBC Driver

トピック:

Oracle ODBC Driverとは

Oracle ODBC Driverを使用すると、Microsoft WindowsおよびLinux、Solaris、IBM Advanced Interactive eXecutive (AIX)などのUNIXプラットフォーム上のアプリケーションで、Oracle Net Servicesソフトウェアを使用し、ODBCインタフェースを介して、Oracleデータベースに対する読取りおよび書込みアクセスができます。

Oracle ODBC Driverは、Oracle Call Interface(OCI)のクライアント/サーバー・ソフトウェアを介して、データソースへの要求の送信およびデータソースからの応答を受信します。OCIクライアントとOracleサーバー間の通信には、Oracle Net Services通信プロトコルが使用されます。

Oracle ODBC Driverは、ODBC SQL構文をデータソースにアクセスできる構文に変換します。データソースから結果が戻されると、Oracle ODBC Driverは戻された結果をODBC SQL構文に変換します。

次の図に、前の段落で説明しているOracle ODBC Driverアーキテクチャを示します。

図24-2 Oracle ODBC Driverアーキテクチャ

図24-2の説明が続きます
「図24-2 Oracle ODBC Driverアーキテクチャ」の説明

* Oracle ODBCリソース・データ定義言語(DLL)ファイル(sqresxx.dllxxは言語の略称)には、言語に関連する全情報が含まれています。使用されるデフォルトのリソース・ファイルはsqresus.dllです。

OCIクライアント/サーバー・ソフトウェアの詳細は、OCIのマニュアルを参照してください。

関連トピック

新機能と変更点

トピック:

Oracle ODBC Driverリリース20c、バージョン20.1.0.0.0の新機能

Oracle ODBC Driverリリース20cの新機能はありません。

Oracle ODBC Driverリリース19c、バージョン19.1.0.0.0の新機能

Microsoft Windows Server 2008、Windows Server 2008 R2、Windows Server 2012、Windows Server 2012 R2、Windows 7、Windows 8、Windows 8.1、Windows 10、Linux X86-64 (32ビット、64ビット)、Sun Solaris SPARC64 (32ビット、64ビット)、IBM AIX 5L (32ビット、64ビット)、Sun Solaris X64 (32ビット、64ビット)、HPUX IA64 (32ビット、64ビット)、ZLinux (32ビット、64ビット)の各オペレーティング・システム用のOracle ODBC Driverリリース19c、バージョン19.1.0.0.0ソフトウェアの新機能はありません。

Oracle ODBC Driverリリース18c、バージョン18.1.0.0.0の新機能

Microsoft Windows Server 2008、Windows Server 2008 R2、Windows Server 2012、Windows Server 2012 R2、Windows 7、Windows 8、Windows 8.1、Windows 10、Linux X86-64 (32/64 bit)、Sun Solaris SPARC64 (32,64 bit)、IBM AIX 5L (32、64ビット)、Sun Solaris X64 (32、64ビット)、HPUX IA64 (32、64ビット), ZLinux (32、64ビット)の各オペレーティング・システム用のOracle ODBC Driverリリース18.1.0.0.0ソフトウェアの機能は、次のとおりです。
  • unixODBC ODBCドライバ・マネージャは、unixODBC–2.3.2からunixODBC–2.3.4にアップグレードされています。

Oracle ODBC Driverリリース12.2.0.1.0の新機能

Microsoft Windows Server 2008、Windows Server 2008 R2、Windows Server 2012、Windows Server 2012 R2、Windows 7、Windows 8、Windows 8.1、Windows 10、Linux X86-64 (32/64 bit)、Sun Solaris SPARC64 (32,64 bit)、IBM AIX 5L (32、64ビット)、Sun Solaris X64 (32、64ビット)、HPUX IA64 (32、64ビット), ZLinux (32、64ビット)の各オペレーティング・システム用のOracle ODBC Driverリリース12.2.0.1.0ソフトウェアの機能は、次のとおりです。

  • 長い識別子のサポートが追加されました。

    Oracle ODBC Driverは、128バイトの長さのオブジェクトをサポートするようになりました。以前のリリースでは、オブジェクトの長さは30バイトに制限されていました。

  • タイムゾーン付きのタイム・スタンプとローカル・タイムゾーン付きのタイム・スタンプのサポートが追加されました。

    この機能は、ODBC TIMESTAMPデータ型が使用されている既存のODBCアプリケーションに対する変更を必要としません。既存のアプリケーションでODBC TIMESTAMP日付型を使用し、データベース列がTIMESTAMPの場合、現在の動作が維持されます。

    データベース列TIMESTAMP WITH TIMEZONEまたはTIMESTAMP WITH LOCAL TIMEZONEでは、ODBC TIMESTAMP_STRUCT内の時間コンポーネントは、ユーザーのセッションタイム・ゾーンにあります。この動作は、ユーザーのアプリケーションに対して透過的なため、ODBCアプリケーションを変更する必要がありません。

Oracle ODBC Driverリリース12.1.0.2.0の新機能

Microsoft Windows Server 2008、Windows Server 2008 R2、Windows Server 2012 、Windows 7、Windows 8、Windows 10、Linux X86-64 (32/64ビット)、Sun Solaris SPARC64 (32、64ビット)、IBM AIX 5L (32、64ビット)、Sun Solaris X64 (32、64ビット)、HPUX IA64 (32、64ビット)、ZLinux (32、64ビット)の各オペレーティング・システム用のOracle ODBC Driverリリース12.1.0.2.0ソフトウェアの機能は、次のとおりです。

Microsoft Windows 10プラットフォームが追加されました。

Oracle ODBC Driverリリース12.1.0.1.0の新機能

Microsoft Windows Server 2008、Windows Server 2008 R2、Windows Server 2012 、Windows 7、Windows 8、Linux X86-64 (32/64ビット)、Sun Solaris SPARC64 (32、64ビット)、IBM AIX 5L (32、64ビット)、Sun Solaris X64 (32、64ビット)、HPUX IA64 (32、64ビット)、ZLinux (32、64ビット)の各オペレーティング・システム用のOracle ODBC Driverリリース12.1.0.1.0ソフトウェアの機能は、次のとおりです。

  • Oracle ODBC Driverは、VARCHAR2NVARCHAR2およびRAWデータで32KBデータ列をサポートするようになりました。

  • odbc.iniファイルまたは接続レベル属性の新しいパラメータ:

    • SQL_TRANSLATE_ERRORS = {T|F} [デフォルトはF (false)]

      SQL翻訳フレームワーク機能を使用している移行済のサード・パーティODBCアプリケーションでは、サーバーから返されるエラーがネイティブ・データベース形式を取ると予想されます。ユーザーは、SQL翻訳フレームワーク・モードで稼働しているOracle DatabaseのSQL翻訳プロファイルにエラーの翻訳を登録できます。エラーの翻訳が登録されたら、ODBCアプリケーションのユーザーはオプションSQLTranslateErrors = Tを有効化し、登録されているとおりのネイティブ・エラーを受け取ることができます。

    詳細は、表24-4を参照してください。

  • Oracle ODBC Driverが、RefCursorを使用せずに暗黙的結果を返すことのできるストアド・プロシージャの実行をサポートするようになりました。このサポートにより、Oracleに移行したサード・パーティのODBCアプリケーションで、旧ベンダーが提供していたこの同じ機能を使用しやすくなります。

  • Oracle Databaseの自動増分機能をサポートするためのSQLColAttribute()フィールド識別子の拡張サポート。Oracle ODBC Driver固有のヘッダー・ファイルsqora.hをアプリケーションに含めることで、この機能を使用できます。

    • SQL_COLUMN_AUTO_INCREMENT

      Oracle Database 12cリリース1 (12.1.0.1)以降では、Oracleが自動増分列をサポートするため、Oracle ODBC Driverは既存のSQLColAttribute()識別子SQL_COLUMN_AUTO_INCREMENTを通じて同じサポートを拡張しました。このプロパティは読取り専用であり、列が自動増分の場合にSQL_TRUEを返し、それ以外の場合にSQL_FALSEを返します。

    • SQL_ORCLATTR_COLUMN_PROP

      Oracle Database 12cリリース1 (12.1.0.1)以降では、Oracle ODBC Driverは、列の属性を返す新しいドライバ固有フィールド識別子SQL_ORCLATTR_COLUMN_PROPをサポートします。この識別子は、次に示すようにすべての列プロパティを持つSQLULEN値を返します。

      +-----------------------------------------+
      | 32 |...| 10 | 9 | 8 |......| 3 | 2 | 1  |
      +-----------------------------------------+
                                     |   |   |
                                     |   |   |-> Column is auto-increment?
                                     |   |-> Auto value is always generated?
                                     |-> If generated by default when null?
      
  • Oracle Database 12cリリース1 (12.1.0.1)でサポートされるODBC API

    • SQLMoreResults()

      暗黙的結果のODBCサポートを実装します。

Oracle ODBC Driverリリース11.2.0.1.0の新機能

Microsoft Windows XP、Microsoft Windows 2003 Server、Microsoft Windows Vista、Linux X86-32 (RHEL AS 4、5)、Linux X86-64 (RHEL AS 4、5) (32/64ビット)、Sun Solaris SPARC64 (9、10) (32/64ビット)、IBM AIX 5L 5.2 (32/64ビット)、Linux IA64 (64ビット)、Linux on Power (32/64ビット)、Sun Solaris X64 (64ビット)、Hewlett Packard Itanium (32/64ビット)オペレーティング・システム用のOracle ODBC Driverリリース11.2.0.1.0ソフトウェアの機能は次のとおりです。

  • LONGおよびLONG RAWデータのプリフェッチ

    Oracle ODBC Driverは、ODBCアプリケーションのパフォーマンスを向上させるために、LONGまたはLONG RAWデータをプリフェッチするように拡張されています。これを行うには、WindowsではLONGデータの最大サイズ(MaxLargeData)をレジストリに設定し(データソース名(DSN)にレジストリ・キーMaxLargeDataを追加する必要もあります)、UNIXプラットフォームではodbc.iniファイルにこれを手動で設定する必要があります。この機能強化により、ユーザーが設定したMaxLargeDataサイズに応じてOracle ODBC Driverのパフォーマンスが最大10倍向上します。MaxLargeDataのデフォルト値は0です。設定できるMaxLargeDataの最大値は64KB (65536バイト)です。

    MaxLargeDataの値が65536より大きい値に設定されていても、フェッチされるデータは65536バイトのみです。データベースに65536バイトより大きいLONGまたはLONG RAWデータがある場合は、単一行のフェッチが行われ、完全なLONGデータがフェッチされるように、MaxLargeDataを0 (デフォルト値)に設定します。ポーリング以外のモードでMaxLargeDataサイズより少ないバッファ・サイズを渡すと、データベースのLONGデータ・サイズがバッファ・サイズより大きい場合には、データの切捨てエラーが発生します。

  • メタデータをフェッチするためのOCIDescribeAny()の使用オプション

    アプリケーションが、REF CURSORSを返す小さなパッケージ・プロシージャを大量にコールする場合、ドライバにOCIDescribeAny()の使用を強制することでパフォーマンスを向上させることができます。このオプションを有効にするには、UNIXプラットフォームで、またWindowsではレジストリを使用して、odbc.iniUseOCIDescribeAnyの値をT (True)に設定します。デフォルト値はF (False)です。

Oracle ODBC Driverリリース11.1.0.1.0の新機能

Windows XP、Linux、SolarisおよびIBM AIXオペレーティング・システム用のOracle ODBC Driverリリース11.1.0.1.0ソフトウェアの機能は次のとおりです。

  • RULEヒントを無効化(DRH接続文字列)

    新しい接続オプション「RULEヒントを無効化」が追加されました。これにより、ユーザーは、カタログAPIでRULEヒントを使用するかどうかを選択するオプションを指定できます。カタログAPIのODBCドライバのパフォーマンスを向上させるための変更が行われました。オプションのデフォルト値は、RULEヒントがカタログAPIで使用されないことを意味するTRUEです。

  • NUMBERをFLOATとしてバインド(BNF接続文字列)

    新しい接続オプション「NUMBERをFLOATとしてバインド」が追加されました。列に浮動小数点データが含まれる場合にFLOATとしてのNUMBER列の列バインディングを導入することにより、バインド変数をFLOATとして使用する問合せ実行が高速になります。

  • 文キャッシング

    各セッションの文のキャッシュを提供および管理するOCI文キャッシュ機能のサポートが追加されました。OCI文のキャッシュ・オプションのサポートを実装することで、ユーザーが同じ接続で同じ文を複数回解析する場合にOracle ODBC Driverのパフォーマンスが向上します。文キャッシュ・フラグのデフォルト値はFALSEです。

Oracle ODBC Driverリリース10.1.0.2.0の新機能

Windows 98、Windows 2000、Windows XPおよびWindows NT X86オペレーティング・システム用のOracle ODBC Driverリリース10.1.0.2.0ソフトウェアの機能は次のとおりです。

  • TIMESTAMPDATEとしてバインド(BTD接続文字列)

    新規の「TIMESTAMPDATEとしてバインド」接続オプションが追加されました。これによりODBCドライバのSQL_TIMESTAMPデータ型を、OracleのTIMESTAMPデータ型ではなくDATEデータ型でバインドできます(これはデフォルトです)。

  • MONTHNAME (exp)ファンクション

    日付式で表される月の名前を返すMONTHNAME (exp)ファンクションのサポートが追加されました。たとえば、「April」などです。

  • DAYNAME (exp)ファンクション

    日付式で表される日の名前を返すDAYNAME (exp)ファンクションのサポートが追加されました。たとえば、「Tuesday」などです。

  • インスタント・クライアントの構成

    インスタント・クライアント・モードの構成がサポートされるようになりました。

Oracle ODBC Driverリリース10.1.0.2.0の変更点

Oracle ODBC Driverリリース10.1.0.2.0で変更された機能、また非推奨機能は次のとおりです。

  • Microsoft Transaction Serverの無効化

    Microsoft Transaction Server (MTS)を無効にするデフォルト設定が、FALSEからTRUEに変更されました。MTSのサポートは、デフォルトで無効になっています。

  • 浮動小数点データ型

    Oracleのデータ型であるBINARY_FLOATおよびBINARY_DOUBLEは、ODBCデータ型のSQL_REALおよびSQL_DOUBLEにそれぞれマップされるように変更されました。

  • SQLGetDataの拡張(GDE接続文字列)

    このリリースでは、SQLGetDataの拡張接続は非推奨です。このオプションの機能は常に使用できます。

  • LONG列の強制取り出し(FRL接続文字列)

    このリリースでは、「LONG列強制取り出し」接続オプションは非推奨です。このオプションの機能は常に使用できます。

  • 「翻訳オプション」構成タブ

    このリリースでは、「Oracle ODBCドライバ構成」ダイアログ・ボックスにあった「翻訳オプション」タブが非推奨になりました。

  • リリース・ノート

    リリース・ノートのファイル名が、ODBCRelnotes.wriからODBCRelnotesUS.htmに変更されました。

関連項目:

サポートされていない機能

現在のOracle ODBC Driverでサポートされていない機能。

Oracle ODBC Driverは、ODBC 3.0の次にあげる機能はサポートしていません。

  • 間隔データ型

  • 共有接続

  • 共有環境

Oracle ODBC Driverでは、次に示すSQL文字列関数はサポートされていません。

  • BIT_LENGTH

  • CHAR_LENGTH

  • CHARACTER_LENGTH

  • DIFFERENCE

  • OCTET_LENGTH

  • POSITION

Oracle ODBC Driverでは、次に示すSQL数値関数はサポートされていません。

  • ACOS

  • ASIN

  • ATAN

  • ATAN2

  • COT

  • DEGREES

  • RADIANS

  • RAND

  • ROUND

Oracle ODBC Driverでは、次に示すSQL関数(時間、日付、間隔)はサポートされていません。

  • CURRENT_DATE

  • CURRENT_TIME

  • CURRENT_TIMESTAMP

  • EXTRACT

  • TIMESTAMPDIFF

インストールによって作成されるファイル

次の表に、Oracle ODBC Driverキットによってインストールされるファイルを示します。

表24-1 Oracle ODBC Driverキットでインストールされるファイル

説明: Windowsインストールのファイル名 UNIXインストールのファイル名

Oracle ODBCデータベース・アクセスDLL

sqora32.dll

libsqora.so.nn.n (nn.nはバージョン番号を表します。例: libsqora.so.20.1)

Oracle ODBC Driver設定DLL

sqoras32.dll

なし

Oracle ODBCリソースDLL

sqresus.dll

なし

日本語用のOracle ODBCリソースDLL

sqresja.dll

なし

Oracle ODBC Driverメッセージ・ファイル

oraodbcus.msb

oraodbcus.msb

日本語用のOracle ODBC Driverメッセージ・ファイル

oraodbcja.msb

oraodbcja.msb

Oracle ODBC Driverリリース・ノート

Oracle Database ODBC Driverリリース・ノート

Oracle Database ODBC Driverリリース・ノート

Oracle ODBC Driver Instant Clientリリース・ノート

ODBC_IC_Readme_Win.html

ODBC_IC_Readme_Unix.html

Oracle ODBC Driverヘルプ・ファイル

sqora.htm

sqora.htm

日本語用のOracle ODBC Driverヘルプ・ファイル

sqora.htm

sqora.htm

Oracle ODBC Driver Instant Clientインストール・スクリプト

odbc_install.exe

odbc_update_ini.sh

Oracle ODBC Driver Instant Clientアンインストール・スクリプト

odbc_uninstall.exe

なし

Microsoftドライバ・マネージャおよびAdministratorファイル

Microsoft ODBC 3.52コンポーネントとともにインストールされるファイルのリストは、Microsoft ODBC 3.52 Software Development Kit and Programmer's Referenceを参照してください。

Microsoft ODBCコンポーネントは、Microsoft Data Access Component (MDAC)キットに含まれています。WindowsのOracle ODBC Driverは、MDACバージョン2.8を使用してテストされています。

unixODBCドライバ・マネージャおよびAdministratorファイル

unixODBCドライバ・マネージャとともにインストールされるファイルのリストは、unixODBCのREADMEファイルおよびINSTALLファイルを参照してください。

関連項目:

ドライバの準拠レベル

ODBCは、次の2つの分野でドライバの準拠レベルを定義しています。

  • ODBCアプリケーション・プログラミング・インタフェース(API)

  • ODBC SQL-99の構文

Oracle ODBC Driverは、APIのすべてのコア機能と、レベル1およびレベル2機能セットの一部をサポートしています。

Oracle ODBC DriverはSQL-92のエントリ・レベル仕様のスーパーセットであるSQL-99のコア仕様と広く互換性があります。SQL-99でサポートされる機能のリストを取得するには、アプリケーションにおいて適切な情報型を指定してSQLGetInfoをコールする必要があります。

関連項目:

コアAPI機能サポートの詳細は、「API準拠」を参照してください

既知の制限事項

次の事項は、Oracle ODBC Driverではサポートされていません。

  • ODBC ASYNCインタフェース

  • アプリケーションでの[Ctrl]+[C]を使用した取消し

構成タスク

トピック:

Oracle Net Servicesの構成

データソースを構成する前に、ネットワーク・データベース・サービスを構成して各Transparent Network Substrate (TNS)サービス名のエントリを構成する必要があります。これを行うには、Oracle Net Configuration Assistant (NETCA)を使用します。

NETCAを使用してtnsnames.oraファイルに各TNSサービス名のエントリを作成できます。Oracle Net Servicesのインストール時に、NETCAもインストールされます。

データソースの構成

注意:

次の構成ステップはWindowsユーザー用です。UNIXユーザーは、odbc_update_ini.shファイルを使用してDSNを作成する必要があります。

Oracle ODBC DriverをインストールしてOracle Net Servicesを構成した後、Oracle ODBC Driverを使用する前に、データソースを構成する必要があります。

アプリケーションとデータソース間で通信を行うには、構成情報が設定されている必要があります。Oracle ODBC Driverは、この構成情報からアクセス対象の情報を取得します。

データソースは、アクセス対象のデータと、それに対応付けられたオペレーティング・システム、データベース管理システムおよびデータベース管理システムにアクセスするためのネットワーク・プラットフォームで構成されます。Oracle ODBC Driverが発行する要求のデータソースはOracleデータベースであり、このデータソースはOracle Net Servicesによるトランスポートをサポートしています。

Oracleデータソースを構成または追加するには

Oracle ODBC Driverをインストールしたら、ODBCデータソース管理者を使用して、各OracleデータベースにOracleデータソースを構成または追加します。Oracle ODBC Driverは、データソースを追加する際にユーザーが入力する情報を使用してデータにアクセスします。次のステップを実行します。

  1. 「スタート」メニューから「プログラム」→「管理ツール」→「データ ソース (ODBC)」を選択します。インストールされているドライバのリストが表示されます。

  2. 新規データ ソースの作成ウィンドウで「追加」をクリックし、インストール済ドライバのリストで「Oracle ODBC Driver」を選択します。

  3. 「終了」をクリックします。「Oracle ODBCドライバ構成」ダイアログ・ボックスが表示されます。DSNとTNSサービス名は必ず入力する必要があります。このダイアログ・ボックスでその他の必要な情報を入力することも、フィールドを空白のままにして、アプリケーションを実行するときに情報を指定することもできます。

  4. データを入力したら、「OK」をクリックするか[Enter]を押します。

データソースはいつでも変更または削除できます。次の項では、データソースの追加、変更または削除方法を説明します。

Oracleデータソースを変更するには

  1. 「スタート」メニューから「プログラム」→「管理ツール」→「データ ソース (ODBC)」を選択します。

  2. 「ODBC データ ソース アドミニストレータ」ダイアログ・ボックスで、データソースのリストからデータソースを選択し、「構成」をクリックします。「Oracle ODBCドライバ構成」ダイアログ・ボックスが表示されます。

  3. 「Oracle ODBCドライバ構成」ダイアログ・ボックスで、必要に応じてオプション値を変更し、「OK」をクリックします。

Oracleデータソースを削除するには

  1. 「スタート」メニューから「プログラム」→「管理ツール」→「データ ソース (ODBC)」を選択します。
  2. 「ODBC データ ソース アドミニストレータ」ダイアログ・ボックスで、データソースのリストから削除するデータソースを選択します。
  3. 「削除」「はい」の順にクリックして、削除を確定します。
「Oracle ODBCドライバ構成」ダイアログ・ボックス

注意:

「Oracle ODBCドライバ構成」ダイアログ・ボックスを使用できるのは、Microsoft Windowsユーザーのみです。

次のスクリーンショットは「Oracle ODBCドライバ構成」ダイアログ・ボックスの例を示したものです。

図24-3 「Oracle ODBCドライバ構成」ダイアログ・ボックス

図24-3の説明が続きます
「図24-3 「Oracle ODBCドライバ構成」ダイアログ・ボックス」の説明

次のリストは、前図に示した「Oracle ODBCドライバ構成」ダイアログ・ボックスにあるメイン設定オプションおよびフィールドの説明です。ダイアログ・ボックスの下半分にあるタブは次以降のトピックで説明します。

  • データソース名(DSN): ODBCでデータソースを識別する名前。たとえば、「odbc-pc」です。DSNは入力する必要があります。

  • 説明: データソースに含まれているデータについての説明やコメント。たとえば、「全従業員の入社日、給与履歴、現行評価」などとします。「説明」フィールドはオプションです。

  • TNSサービス名: ODBCドライバがデータを取得するOracleデータベースの位置。これは、Oracle Net Servicesを構成したときに、Oracle Net Configuration Assistant (NETCA)を使用して入力したものと同じ名前です。詳細は、NETCAのマニュアルと「Oracle ODBC Driverの最初の使用について」を参照してください。TNSサービス名は、使用可能なTNS名のプルダウン・リストから選択できます。たとえば、「ODBC-PC」です。TNSサービス名を入力する必要があります。

  • ユーザーID: データにアクセスするために使用するサーバー上のアカウントのユーザー名です。たとえば、「scott」です。「ユーザーID」フィールドはオプションです。

DSNとTNSサービス名は必ず入力する必要があります。このダイアログ・ボックスでその他の情報を入力することも、フィールドを空白のままにして、アプリケーションを実行するときに情報を指定することもできます。

前述のメイン設定オプションの他に、「接続テスト」ボタンがあります。このボタンは、DSN定義で指定されたデータベースに接続することによってODBC環境が適切に構成されているかを確認します。「接続テスト」ボタンを押し、ユーザー名およびパスワードを入力してください。

「Oracle ODBCドライバ構成」ダイアログ・ボックスの下半分にあるオプション・タブの説明は、次のリンクのいずれかをクリックします。

アプリケーション・オプション

Oracleオプション

Workaroundsオプション

SQL Server移行オプション

アプリケーション・オプション

次のスクリーンショットは、「Oracle ODBCドライバ構成」ダイアログ・ボックスにある「アプリケーション」タブの例を示したものです。

図24-4 「Oracle ODBCドライバ構成」ダイアログ・ボックスの「アプリケーション」オプション・タブ

図24-4の説明が続きます
「図24-4 「Oracle ODBCドライバ構成」ダイアログ・ボックスの「アプリケーション」オプション・タブ」の説明

次のリストは、前図で示した「アプリケーション」タブにあるフィールドの説明です。

  • 結果セットを有効化: Oracle結果セットの処理を有効にします。結果セットがアプリケーションに必要ない場合、結果セットのサポートを無効にできます。パッケージからの結果セットを含んでいないプロシージャ・コールは、少々パフォーマンスが低下します。デフォルトでは、結果セットは有効です。

  • 問合せタイムアウトを有効化: SQL問合せで、タイムアウトを有効にします。デフォルトでは、Oracle ODBC DriverはSQLSetStmtAttr関数用にSQL_ATTR_QUERY_TIMEOUT属性をサポートします。このボックスが選択されていない場合、Oracle ODBC Driverは、「不可」メッセージを返します。デフォルトでは、問合せタイムアウトは有効です。

  • 読取専用接続: 読取り専用アクセスを指定するには、このボックスを選択します。デフォルトは、書込み可能な接続です。

  • カーソル・クローズを有効化: カーソル・クローズを有効にします。デフォルトでは、カーソル・クローズは無効(フィールドが空)になっています。これは、不必要なパフォーマンス低下の原因となるためこの動作が望ましくない場合に、カーソルのクローズをコールしてもOCIカーソルのクローズが強制されないことを意味します。カーソルのクローズをコールしたときにOCIカーソルを強制的にクローズする場合は、カーソル・クローズを有効にします。

注意:

カーソルがクローズされるたびに、パフォーマンスに影響があります。

  • スレッド・セーフティを有効化: データソースについてスレッド・セーフティを無効にすることもできます。スレッド・セーフティが不要な場合は、このオプションを指定しなければスレッド・セーフティのオーバーヘッドをなくすことができます。デフォルトではスレッド・セーフティは有効です。

  • バッチ自動コミット・モード: デフォルトでは、すべての文が成功した場合、コミットが実行されます。

  • 数値の設定: 文字列としてバインドされた数値データの受渡しで、どの数値設定を使用して小数点文字や3桁セパレータを決定するかを指定します。このオプションでは、Oracle NLSの設定(デフォルトの設定)、Microsoftのデフォルトの地域設定(Oracle OLE DBドライバの動作とあわせて相互運用性を向上)、US数値設定(英語環境以外でMS AccessまたはDAO (Database Access Object)を使用する際に必要)の選択ができます。

関連項目:

メイン構成設定オプションは、「「Oracle ODBCドライバ構成」ダイアログ・ボックス」を参照してください

Oracleオプション

次のスクリーンショットは、「Oracle ODBCドライバ構成」ダイアログ・ボックスにあるOracleオプション・タブの例を示したものです。

図24-5 「Oracle ODBCドライバ構成」ダイアログ・ボックスの「Oracle」オプション・タブ

図24-5の説明が続きます
「図24-5 「Oracle ODBCドライバ構成」ダイアログ・ボックスの「Oracle」オプション・タブ」の説明

次のリストは、前図で示した「Oracle」タブにあるフィールドの説明です。

  • フェッチ・バッファ・サイズ: 単一の問合せでアプリケーション・プログラムがリクエストする行数に関係なく、ODBCドライバがOracle Databaseから一度にプリフェッチするデータの行数を決定するために使用されるメモリー量。ただし、プリフェッチされる行数は、単一の問合せで指定された列の幅と数に依存します。通常一度に20行未満をフェッチするアプリケーションでは、低速なネットワーク接続上で動作する場合や非常に負荷の高いサーバーにアクセスする場合には特に、レスポンス時間が向上します。フェッチ・バッファ・サイズを大きく設定しすぎると、レスポンス時間が悪化したり、メモリーを大量に消費することがあります。

注意:

LONGおよびLOBデータ型がある場合、ODBCドライバのプリフェッチ行数は、フェッチ・バッファ・サイズに依存しません。LONGおよびLOBデータ型では、パフォーマンスの改善が見込めず、過度のメモリー消費を引き起こす可能性があります。LONGおよびLOBデータ型が存在する場合にのみ、ODBC Driverはフェッチ・バッファ・サイズを無視し、既定の行数をプリフェッチします。

  • LOBを有効化: Oracle LOBの書込みを可能にします。アプリケーションにOracle LOBの書込みが不要であれば、LOBのサポートは無効にできます。LOBを有効にすると、INSERT文とUPDATE文の処理時にわずかながらパフォーマンスが低下します。LOBの書込みはデフォルトで有効ですが、LOBデータ型をサポートしないOracleデータベースでは無効になります。

  • ステートメントのキャッシングを有効化: 文キャッシュ機能を有効にします。これにより、ユーザーが問合せおよび関連パラメータの同じテキストを複数回解析する必要がある場合に、問合せの解析パフォーマンスが向上します。デフォルトでは無効になります。

  • キャッシュバッファサイズ: 文のキャッシュには、サービス・コンテキスト(OCI_ATTR_STMTCACHESIZE)の属性を使用して変更可能な最大サイズ(文の数)があります。デフォルトのキャッシュ・バッファ・サイズは20で、文キャッシングのオプションが有効化されている場合にのみ使用されます。キャッシュ・バッファ・サイズを0に設定すると、文のキャッシング機能は無効になります。

  • 最大トークン・サイズ: トークン・サイズを4KB (4096バイト)から開始する最も近い1KB (1024バイト)の倍数に設定します。デフォルト・サイズは8KB (8192バイト)です。設定できる最大値は128KB (131068バイト)です。

  • ORAエラーを変換 - SQL翻訳フレームワーク機能を使用している移行済のサード・パーティODBCアプリケーションでは、サーバーから返されるエラーがネイティブ・データベース形式を取ると予想されます。このオプションを有効にすると、SQL翻訳プロファイルに登録されているエラー翻訳に基づいたネイティブ・エラーを受け取ることができます。

  • 「Oracle」オプション・タブの「フェイルオーバー」領域には次のフィールドがあります:

    • フェイルオーバーを有効化: Oracle Fail SafeとOracle Parallel Serverのフェイルオーバーの再試行を有効にします。このオプションは、Oracle Fail SafeとOracle Parallel Serverのフェイルオーバー機能に対する拡張です。このオプションで追加フェイルオーバー再試行が構成可能になります。デフォルトは有効です。

    • 再試行: 接続のフェイルオーバーを試みる回数。デフォルトは10回です。

    • 遅延: フェイルオーバーを試みる間隔の秒数。デフォルトは10秒です。

  • 集計SQLタイプ - 集計関数で返される数値型(SQL_FLOATSQL_DOUBLEまたはSQL_DECIMAL)を指定します。

  • LOBプリフェッチ・サイズ - 一度にデータベースからプリフェッチするLOBデータの量(バイト単位)を設定します。デフォルト・サイズは8192です。

注意:

Oracle Fail Safeは非推奨で、今後のリリースではサポート対象外になり、使用できなくなる可能性があります。Oracle RAC One Nodeなどの他の単一ノード・フェイルオーバー・オプションを評価することをお薦めします

注意:

Oracle Fail SafeとOracle Parallel Serverの設定や使用方法については、それぞれの製品のドキュメントを参照してください。

関連項目:

メイン構成設定オプションは、「「Oracle ODBCドライバ構成」ダイアログ・ボックス」を参照してください

Workaroundsオプション

次のスクリーンショットは、「Oracle ODBCドライバ構成」ダイアログ・ボックスにあるWorkaroundsオプション・タブの例を示したものです。

図24-6 「Oracle ODBCドライバ構成」ダイアログ・ボックスの「Workarounds」オプション・タブ

図24-6の説明が続きます
「図24-6 「Oracle ODBCドライバ構成」ダイアログ・ボックスの「Workarounds」オプション・タブ」の説明

次のリストは、前図で示した「Workarounds」タブにあるフィールドの説明です。

  • TIMESTAMPをDATEとしてバインド - このボックスを選択すると、Oracle ODBC Driverにより、SQL_TIMESTAMPパラメータがOracleのTIMESTAMP型(デフォルト)ではなくOracle DATE型で強制的にバインドされます。

  • SQL_WCHAR強制サポート: このボックスを選択すると、SQLDescribeCol、SQLColumnsおよびSQLProcedureColumnsにより、SQL_CHAR列にはSQL_WCHARのデータ型、SQL_VARCHAR列にはSQL_WVARCHARのデータ型、およびSQL_LONGVARCHAR列にはSQL_WLONGVARCHARのデータ型がそれぞれ無条件で戻されるようになります。この機能により、これらのODBCコールの結果に依存するアプリケーション(たとえば、ADOアプリケーション)でのUnicodeのサポートが可能になります。デフォルトでは、このサポートは無効になっています。

  • MTS無効: このボックスの選択を解除すると、Microsoft Transaction Server (MTS)サポートが有効になります。MTSのサポートは、デフォルトで無効になっています。

  • METADATA IDデフォルトにSQL_TRUEをセット: このボックスを選択すると、SQL_ATTR_METADATA_ID接続と接続時の文属性のデフォルト値がSQL_TRUEに変更されます。通常ではSQL_ATTR_METADATA_IDSQL_FALSEがデフォルトです。接続後に明示的に属性値を変更するアプリケーションのODBCコールが、このオプションにより影響を受けることはなく、関数は問題なく終了します。デフォルトでは、このオプションは無効です。

  • LONG列データのサイズをプリフェッチ: LONGまたはLONG RAWデータをプリフェッチしてODBCアプリケーションのパフォーマンスを向上させるには、この値を設定します。この機能強化により、ユーザーが設定したプリフェッチ・サイズに応じてOracle ODBC Driverのパフォーマンスが最大10倍向上します。デフォルトの値は0。設定できる最大値は64KB (65536バイト)です。

    プリフェッチ・サイズの値が65536より大きい値に設定されていても、フェッチされるデータは65536バイトのみです。データベースに65536バイトより大きいLONGまたはLONG RAWデータがある場合は、単一行のフェッチが行われ、完全なLONGデータがフェッチされるように、プリフェッチ・サイズを0 (デフォルト値)に設定します。ポーリング以外のモードでプリフェッチ・サイズより少ないバッファ・サイズを渡すと、データベースのLONGデータ・サイズがバッファ・サイズより大きい場合には、データの切捨てエラーが発生します。

  • SQLDescribeParamを無効化: SQLDescribeParam関数が有効な場合、すべてのパラメータに対してSQL_VARCHARデータ型が戻されます。SQL_WCHAR強制サポート関数も有効な場合は、すべてのパラメータに対してSQL_WVARCHARデータ型が戻されます。デフォルトでは、この関数は有効です。

  • NUMBERをFLOATとしてバインド - このボックスを選択すると、Oracle ODBC Driverで、FLOATデータを含むNUMBER列がBinary Float (デフォルト)ではなくFLOATとしてバインドされます。

  • RULEヒントを無効化: このボックスの選択を解除すると、カタログ問合せで指定されているRULE Hintが有効になります。デフォルトでは、RULE Hintのオプションは無効です。

  • OCIDescribeAnyを使用: このボックスを選択すると、アプリケーションがREF CURSORSを戻す小さなパッケージ・プロシージャを頻繁にコールする場合にドライバにOCIDescribeAny()の使用を強制することで、パフォーマンスが向上します。

関連項目:

SQL Server移行オプション

次のスクリーンショットは、「Oracle ODBCドライバ構成」ダイアログ・ボックスにあるSQL Server移行オプション・タブの例を示したものです。

図24-7 「Oracle ODBCドライバ構成」ダイアログ・ボックスの「SQLServer Migration」オプション・タブ

図24-7の説明が続きます
「図24-7 「Oracle ODBCドライバ構成」ダイアログ・ボックスの「SQLServer Migration」オプション・タブ」の説明

前の図の「SQLServer Migration」オプション・タブのフィールドは次のとおりです。

  • Enable EXEC Syntax: SQL Server EXEC構文のサポートを有効にします。Oracle Databaseサーバーによって処理される前に、EXEC文で指定されるサブプログラム・コールは、対応するOracleサブプログラム・コールに変換されます。デフォルトではこのオプションは無効になっています。

  • スキーマ: 変換されたOracleサブプログラムは、ユーザーのデフォルト・スキーマに定義されます。ただし、同じSQL Serverデータベースからのすべてのサブプログラムを、データベース名をスキーマ名としてOracleスキーマに移行する場合、このフィールドは「データベース」に設定します。同じSQL Serverユーザーに所有されていたすべてのサブプログラムを同じOracleスキーマに定義する場合、このフィールドは「オーナー」に設定します。デフォルトでは、このフィールドは空欄になっています。

関連項目:

メイン構成設定オプションは、「「Oracle ODBCドライバ構成」ダイアログ・ボックス」を参照してください

oraodbc.iniファイルの変更

トピック:

ロック・タイムアウトの短縮

Oracleサーバーは、トランザクション間のロック競合が解消されるまで無期限に待機します。Oracle ODBC Driverのoraodbc.iniファイルのLockTimeOutエントリを設定することで、Oracleサーバーがロックの解消を待機する時間を制限できます。LockTimeOutパラメータに入力する値は、Oracleサーバーがリクエストしたロックを取得できない場合にタイムアウトになるまでの秒数です。次の例では、Oracleサーバーは60秒後にタイムアウトになります。

[Oracle ODBC Driver Common]
LockTimeOut=60

データソースへの接続

トピック:

Oracleデータソースへの接続

Oracle ODBC Driverでは、データソースに接続するために、使用するコンピュータにOCIクライアント・ソフトウェアがインストールされていて、対応するリスナーがOracleサーバーで実行されていることが必要です。Oracle Net Services for Windowsは、ダイナミック・リンク・ライブラリ(DLL)に基づくアプリケーションです。Oracle Net Servicesの詳細は、Oracle Net Servicesのマニュアルを参照してください。

接続処理の一部として、アプリケーションがユーザーに情報を要求することがあります。アプリケーションからOracleデータソースについての情報を要求された場合は、次の手順を実行します。

  1. 「TNSサービス名」ボックスで、TNSサービス名の名前を入力します。
  2. 「ユーザー名」ボックスに、Oracleデータベースにアクセスするために使用する名前を入力します。
  3. 「パスワード」ボックスに、Oracleデータベースにアクセスするために使用するパスワードを入力します。
  4. 「OK」をクリックします。

アプリケーションは、データソース内のデータにアクセスするにはデータソースに接続する必要があります。データソースに接続するタイミングは、アプリケーションによって異なります。たとえば、アプリケーションがユーザーの要求時にのみデータソースに接続する場合もあれば、起動時に自動的に接続する場合もあります。アプリケーションがいつデータソースに接続するかは、そのアプリケーションのマニュアルを参照してください。

追加情報にアクセスするには、次のリンクのいずれかをクリックします。

トラブルシューティング

トピック:

Oracle ODBC Driverの最初の使用について

Oracle ODBC Driverを初めて使用する際に役立つ情報について説明します。

Oracle ODBC Driver開発者のホーム「ODBC Developer Center」を参照してください。ここでは、Oracle ODBC Driverの機能やOracle Instant Client ODBCのインストール・ガイド、Oracle Instant Client ODBCのダウンロード・サイト、Oracle ODBCのディスカッション・フォーラム、Oracle ODBC Driverの開発ガイドおよび関連技術に関する情報などのリソースを入手できます。

パスワードの期限切れ

この項には、期限切れパスワードに関する情報が含まれます。

期限切れパスワードの動作

データベースの接続時にパスワードが期限切れの場合、パスワードを変更するよう要求されます。正常にパスワードが変更されると、データベースに接続されます。ただし、SQL_DRIVER_NOPROMPTパラメータ値を使用してSQLDriverConnectコールでデータベースに接続すると、Oracle ODBC Driverはパスワードを変更するよう要求しません。かわりにエラーとなり、パスワードが期限切れであることを示すエラー番号およびメッセージを表示します。

上級ユーザー

トピック:

Oracle ODBC DriverのTNSサービス名の作成

Oracle Net Servicesを使用してOracle ODBC DriverのTNSサービス名を作成するには、Oracle Net Servicesと同時にインストールされるOracle Net Configuration Assistant (NETCA)を使用します。NETCAによって、Oracle ODBC DriverのTNSサービス名のエントリがtnsnames.oraファイルに作成されます。

SQL文

Oracle ODBC DriverはSQL-92のエントリ・レベル仕様のスーパーセットであるSQL-99のコア仕様と広く互換性があります。Oracleの文法に加えて、ODBC仕様の付録Cで概要を説明しているベンダー固有のエスケープ・シーケンスもサポートしています。ODBCの設計に従って、Oracle ODBC Driverは固有のSQL構文をOracle Databaseに渡します。

関連項目:

データ型

Oracleデータベースのデータ型はOracle ODBC DriverによってODBCのSQLデータ型にマップされます。

注意:

Microsoft ODBC 3.52 Software Development Kit and Programmers ReferenceのAppendix Dにあるすべての変換は、適切な情報型を指定したSQLGetInfoのコールでリストされるODBC SQLデータ型についてサポートされています。

データ型の実装

トピック:

DATEおよびTIMESTAMP

OracleのDATEおよびTIMESTAMPデータ型のセマンティクスは、同名のODBCデータ型と必ずしも正確に対応していません。OracleのDATEデータ型には日付情報および時間情報の両方が、SQL_DATEデータ型には日付情報のみが含まれます。OracleのTIMESTAMPデータ型にも日付と時間の情報が格納されていますが、その小数秒の精度は他方に比較して高くなります。ODBCドライバでは、OracleのDATEおよびTIMESTAMP列の両方のデータ型がSQL_TIMESTAMPとしてレポートされ、情報の紛失が回避されています。また、ODBCドライバにより、SQL_TIMESTAMPパラメータがOracleのTIMESTAMP値としてバインドされます。

浮動小数点データ型

リリース10.1以降のOracleサーバーに接続すると、ODBCドライバにより、Oracleの浮動小数点のデータ型であるBINARY_FLOATおよびBINARY_DOUBLEが、ODBCデータ型であるSQL_REALおよびSQL_DOUBLEにそれぞれマップされます。以前のリリースでは、SQL_REALおよびSQL_DOUBLEがOracleの汎用数値データ型にマップされていました。

データ型に関する制限事項

Oracle ODBC DriverおよびOracleデータベースでは、データ型について制限があります。次の表に制限事項を示します。

表24-2 Oracle ODBC DriverおよびOracle Databaseデータ型に関する制限事項

制限されるデータ型 説明:

リテラル

Oracle DatabaseではSQL文内のリテラルが32Kバイトに制限されます。

SQL_LONGVARCHARおよびSQL_WLONGVARCHAR

SQL_LONGVARCHARデータ(LONG型)のOracleでの制限は2,147,483,647バイトです。SQL_LONGVARCHARデータ(CLOB型)のOracleでの制限は4GBです。これは、クライアント・ワークステーションのメモリーによる制限です。

SQL_LONGVARCHARおよびSQL_LONGVARBINARY

Oracleデータベースでは1つの表ではLONGデータ列を1つしか使用できません。LONGデータ型とは、SQL_LONGVARCHAR(LONG)およびSQL_LONGVARBINARY(LONG RAW)です。かわりにCLOBおよびBLOBを使用することをお薦めします。1つの表で使用できるCLOBおよびBLOBの列数に制限はありません。

エラー・メッセージ

エラーが発生すると、Oracle ODBC Driverは固有のエラー番号、SQLSTATE (ODBCエラー・コード)およびエラー・メッセージを戻します。ドライバが検出したエラーとOracleサーバーが戻したエラーの両方から、この情報を導出します。

固有のエラー

データソースで発生したエラーについては、Oracle ODBC DriverはOracleサーバーから戻された固有のエラーを戻します。Oracle ODBC Driverまたはドライバ・マネージャがエラーを検出した場合は、Oracle ODBC Driverは0 (ゼロ)という固有のエラーを戻します。

SQLSTATE

データソースで発生したエラーについては、Oracle ODBC Driverは戻された固有のエラーを適切なSQLSTATEにマップします。Oracle ODBC Driverがエラーを検出した場合は、Oracle ODBC Driverが適切なSQLSTATEを生成します。ドライバ・マネージャがエラーを検出した場合は、ドライバ・マネージャが適切なSQLSTATEを生成します。

エラー・メッセージ

データソースで発生したエラーについては、Oracle ODBC DriverはOracleサーバーから戻されたメッセージに基づくエラー・メッセージを戻します。Oracle ODBC Driverまたはドライバ・マネージャで発生したエラーについては、Oracle ODBC DriverはSQLSTATEに関連するテキストに基づくエラー・メッセージを戻します。

エラー・メッセージの書式は次のとおりです。

[vendor] [ODBC-component] [data-source] error-message

大カッコ([ ])内の接頭辞によってエラーのソースが識別されます。次の表に、Oracle ODBC Driverから返される接頭辞の値を示します。エラーがデータソースで発生したときは、[vendor]および[ODBC-component]という接頭辞によって、ベンダーと、データソースからエラーを受け取るODBCコンポーネントの名前が識別されます。

表24-3 Oracle ODBC Driverが戻す接頭辞のエラー・メッセージ値

エラー・ソース 接頭辞

ドライバ・マネージャ

[vendor][ODBC-component][data-source]

[Microsoft/unixODBC][ODBC Driver Manager]N/A

Oracle ODBC Driver

[vendor][ODBC-component][data-source]

[ORACLE][ODBC Driver]N/A

Oracleサーバー

[vendor][ODBC-component][data-source]

[ORACLE][ODBC Driver]N/A

たとえば、次に示すフォーマットのようにエラー・メッセージに[Ora]という接頭辞が含まれない場合、そのエラーはOracle ODBC Driverのエラーであり、自明であるために接頭辞が省略されています。

[Oracle][ODBC]Error message text here

次に示すフォーマットのようにエラー・メッセージに[Ora]という接頭辞が含まれる場合、Oracle ODBC Driverのエラーではありません。

注意:

エラー・メッセージに接頭辞[Ora]が含まれていても、実際のエラーはいくつかのソースの1つで発生している可能性があります。

[Oracle][ODBC][Ora]Error message text here

エラー・メッセージのテキストが次に示す接頭辞で始まる場合は、そのエラーについての詳しい情報がOracleサーバーのマニュアルに記載されています。

ORA-

Oracle Net Servicesエラーおよびトレース・ロギングは、OCIソフトウェアがインストールされたWindowsシステムのORACLE_HOME\NETWORKディレクトリまたはUNIXシステムのORACLE_HOME/NETWORKディレクトリの下、具体的にはそれぞれlogディレクトリとtraceディレクトリにあります。データベース・ロギングは、Oracleサーバー・ソフトウェアがインストールされたWindowsシステムのORACLE_HOME\RDBMSディレクトリまたはUNIXシステムのORACLE_HOME/rdbmsディレクトリにあります。

サーバーのエラー・メッセージの詳細は、Oracleサーバーのマニュアルを参照してください。

プログラマ

トピック:

接続文字列のフォーマット

次の表に、SQLDriverConnect関数コールの接続文字列引数に組み込むことができるキーワードを示します。指定されていないキーワードは、データソースのAdministratorのエントリから読み込まれます。接続文字列に指定される値はAdministratorのエントリに格納されている値を上書きします。SQLDriverConnect関数の詳細は、Microsoft ODBC 3.52 Software Development Kit and Programmers Referenceを参照してください。

表24-4 SQLDriverConnect関数コールの接続文字列引数に組み込むことができるキーワード

キーワード 意味 コメント

DSN

ODBCデータソース名

ユーザー指定の名前。

DBQ

TNSサービス名

ユーザー指定の名前。

UID

ユーザーIDまたはユーザー名

ユーザー指定の名前。

PWD

パスワード

ユーザー指定パスワード。空のパスワードに対しては、PWD=;と指定。

DBA

データベース属性

W=書込みアクセス。

R=読取り専用アクセス。

APA

アプリケーション属性

T=スレッド・セーフティ有効。

F=スレッド・セーフティ無効。

RST

結果セット

T=結果セット有効。

F=結果セット無効。

QTO

問合せタイムアウト・オプション

T=クエリー・タイムアウト有効。

F=クエリー・タイムアウト無効。

CSR

カーソルのクローズ

T=カーソル・クローズ有効。

F=カーソル・クローズ無効。

BNF

NUMBERFLOATとしてバインド

T=NUMBERFLOATとしてバインド。

F=NUMBERNUMBERとしてバインド。

DRH

RULEヒントを無効化

T=RULEヒントを無効化。

F=RULEヒントを有効化。

BAM

バッチ自動コミット・モード

IfAllSuccessful=すべての文が成功した場合のみコミット(古い動作)。

UpToFirstFailure=最初に失敗した文までコミット(V7 ODBCの動作)。

AllSuccessful=すべての成功した文をコミット(Oracle Databaseに接続している場合のみ、その他のデータベースでは、V7と同じ動作)。

FBS

フェッチ・バッファ・サイズ

ユーザー指定の数値(バイト単位で0以上を指定)。

デフォルトは60,000バイドです。

FEN

フェイルオーバー

T=フェイルオーバー有効。

F=フェイルオーバー無効。

FRC

フェイルオーバー再試行数

ユーザー指定の数値。

デフォルト値は10です。

FDL

フェイルオーバー遅延

ユーザー指定の数値。

デフォルト値は10です。

LOB

LOB書込み

T=LOB有効。

F=LOB無効。

MTS

Microsoft Transaction Serverサポート

T=無効。

F=有効。

FWC

SQL_WCHAR強制サポート

T=強制SQL_WCHAR有効。

F=強制SQL_WCHAR無効。

EXC

EXEC構文

T=EXEC構文有効。

F=EXEC構文無効。

XSM

スキーマ・フィールド

Default=デフォルト。

Database=データベース名。

Owner=所有者名。

MDI

メタデータIDのデフォルトの設定

T=SQL_ATTR_METADATA_IDのデフォルトをSQL_TRUEに設定。

F=SQL_ATTR_METADATA_IDのデフォルトをSQL_FALSEに設定。

DPM

SQLDescribeParamの無効化

T=SQLDescribeParam無効。

F=SQLDescribeParam有効。

BTD

TIMESTAMPDATEとしてバインド

T=SQL_TIMESTAMPをOracle DATEでバインド。

F=SQL_TIMESTAMPをOracle TIMESTAMPでバインド。

NUM

数値の設定

NLS=Oracle NLS数値設定を使用(小数点および3桁区切りの決定)。

MS=Microsoft地域設定を使用。

US=US設定を使用。

ODA

OCIDescribeAny( )の使用

T=アプリケーションがREF CURSORSを戻す小さなパッケージ・プロシージャを頻繁にコールする場合にパフォーマンスを向上させるためにOCIDescribeAny()コールを使用。

F=OCIDescribeAny()を使用しない。デフォルトでは、OCIDescribeAny()値の使用はFALSEです。

STE

SQLでORAエラーを変換

Oracle ODBC DriverがOracleエラー・コードを変換するかどうかを指定

T=ORAエラーを変換。

F=ORAエラーを変換しない。デフォルトでは、SQLTranslateErrorsFALSEです。

TSZ

トークン・サイズ

ユーザー指定の数値。

トークン・サイズを4KB (4096バイト)から開始する最も近い1KB (1024バイト)の倍数に設定します。デフォルト・サイズは8KB (8192バイト)です。設定できる最大値は128KB (131068バイト)です。

次のキーワードが接続文字列に指定された場合、Oracle ODBC DriverはAdministratorで定義されている値を読み取りません。

DRIVER={Oracle ODBC Driver}

有効な接続文字列の例:

1) DSN=Personnel;UID=Kotzwinkle;PWD=;2) DRIVER={Oracle ODBC Driver};UID=Kotzwinkle;PWD=whatever;DBQ=instl_alias;DBA=W;

関連項目:

SQLDriverConnectの実装

次の表に、SQLDriverConnect接続文字列で必要なキーワードを示します。

表24-5 SQLDriverConnect接続文字列で必要なキーワード

キーワード 説明:

DSN

データソース名。

DBQ

TNSサービス名。「Oracle ODBC DriverのTNSサービス名の作成」を参照してください。詳細は、Oracle Net Servicesのマニュアルを参照してください。

UID

ユーザーのログインIDまたはユーザー名。

PWD

ユーザー指定のパスワード。

プログラムでのロック・タイムアウトの短縮

Oracleサーバーは、トランザクション間のロック競合が解消されるまで無期限に待機します。データソースに接続する前にODBC SQLSetConnectAttr関数をコールすることによって、ロック解消をOracleサーバーが待機する時間の長さを制限できます。ODBC SQLSetStmtAttr関数のSQL_ATTR_QUERY_TIMEOUT属性に0 (ゼロ)以外の値を指定します。

ODBC SQLSetConnectAttr関数を使用してロック・タイムアウト値を指定すると、その値によってoraodbc.iniファイルに指定されている値が上書きされます。

関連項目:

oraodbc.iniファイルに値を指定する方法の詳細は、「ロック・タイムアウトを短縮する」を参照してください

odbc32.lib (Windows)またはlibodbc.so (UNIX)とのリンク

Windowsプラットフォームの場合、プログラムをリンクするときは、インポート・ライブラリodbc32.libとリンクする必要があります。

UNIXプラットフォームの場合は、ODBCアプリケーションをlibodbc.soにリンクする必要があります。

ROWIDの情報

ODBCのSQLSpecialColumns関数は、表内の列に関する情報を返します。Oracle ODBC Driverでは、Oracle表に対応付けられているOracleのROWIDについての情報が戻されます。

WHERE句でのROWID

ROWIDはSQL文のWHERE句で使用できます。ただし、ROWID値はパラメータ・マーカー内で使用する必要があります。

結果セットの有効化

Oracleの参照カーソル(結果セット)によって、アプリケーションはストアド・ファンクションやストアド・プロシージャを使用してデータを取り出せるようになります。次にODBCを介して結果セットを使用可能にする方法を示します。

  • ストアド・プロシージャのコールにはODBC構文を使用する必要があります。システム固有のPL/SQLは、ODBCを介してサポートされていません。次にパッケージ内のおよびパッケージなしのプロシージャまたはファンクションのコール方法を示します。ここでのパッケージ名をRSETとします。

    Procedure call: 
    {CALL Example1(?)}
    {CALL RSET.Example1(?)} 
    Function Call: 
    {? = CALL Example1(?)}
    {? = CALL RSET.Example1(?)} 
    
  • PL/SQLの参照カーソル・パラメータは、プロシージャのコール時には省略されます。たとえば、Example2プロシージャが4つのパラメータを持つと仮定します。パラメータ1と3は参照カーソル・パラメータで、パラメータ2と4は文字列です。コールは、次のように指定されます。

    {CALL RSET.Example2("Literal 1", "Literal 2")}
    

次のサンプル・アプリケーションでは、Oracle ODBC Driverを使用して結果セットを返す方法を示します。

/*
 * Sample Application using Oracle reference cursors via ODBC
 *
 * Assumptions:
 *
 * 1) Oracle Sample database is present with data loaded for the EMP table.
 * 2) Two fields are referenced from the EMP table ename and mgr.
 * 3) A data source has been setup to access the sample database.
 *
 * Program Description:
 *
 * Abstract:
 *
 * This program demonstrates how to return result sets using
 * Oracle stored procedures
 *
 * Details:
 *
 * This program:
 * Creates an ODBC connection to the database.
 * Creates a Packaged Procedure containing two result sets.
 * Executes the procedure and retrieves the data from both result sets.
 * Displays the data to the user.
 * Deletes the package then logs the user out of the database.
 *
 *
 * The following is the actual PL/SQL this code generates to
 * create the stored procedures.
 *
 * DROP PACKAGE ODBCRefCur;
 *
 * CREATE PACKAGE ODBCRefCur AS
 * TYPE ename_cur IS REF CURSOR;
 * TYPE mgr_cur IS REF CURSOR;
 * PROCEDURE EmpCurs(Ename IN OUT ename_cur, Mgr IN OUT mgr_cur, pjob IN VARCHAR2);
 * END;
 *
 * CREATE or REPLACE PACKAGE BODY ODBCRefCur AS
 * PROCEDURE EmpCurs(Ename IN OUT ename_cur, Mgr IN OUT mgr_cur, pjob IN VARCHAR2)
 * AS
 * BEGIN
 * IF NOT Ename%ISOPEN
 * THEN
 * OPEN Ename for SELECT ename from emp;
 * END IF;
 * IF NOT Mgr%ISOPEN
 * THEN
 * OPEN Mgr for SELECT mgr from emp where job = pjob;
 * END IF;
 * END;
 * END;
 *
 */

/* Include Files */
#ifdef WIN32
  #include <windows.h>
#endif
#include <stdio.h>
#include <sql.h>
#include <sqlext.h>
 
/* Defines */
#define JOB_LEN 9
#define DATA_LEN 100
#define SQL_STMT_LEN 500
 
/* Procedures */
void DisplayError(SWORD HandleType, SQLHANDLE hHandle, char *Module);
 
/* Main Program */
int main()
{
  SQLHENV hEnv;
  SQLHDBC hDbc;
  SQLHSTMT hStmt;
  SQLRETURN rc;
  char *DefUserName ="scott";
  char *DefPassWord ="tiger";
  SQLCHAR ServerName[DATA_LEN];
  SQLCHAR *pServerName=ServerName;
  SQLCHAR UserName[DATA_LEN];
  SQLCHAR *pUserName=UserName;
  SQLCHAR PassWord[DATA_LEN];
  SQLCHAR *pPassWord=PassWord;
  char Data[DATA_LEN];
  SQLINTEGER DataLen;
  char error[DATA_LEN];
  char *charptr;
  SQLCHAR SqlStmt[SQL_STMT_LEN];
  SQLCHAR *pSqlStmt=SqlStmt;
  char *pSalesMan = "SALESMAN";
  SQLINTEGER sqlnts=SQL_NTS;

  /* Allocate the Environment Handle */
  rc = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv );
  if (rc != SQL_SUCCESS)
  {
    printf( "Cannot Allocate Environment Handle/n");
    printf( "/nHit Return to Exit/n");
    charptr = gets ((char *)error);
    exit(1);
  }

  /* Set the ODBC Version */
  rc = SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0);
  if (rc != SQL_SUCCESS)
  {
    printf("Cannot Set ODBC Version/n");
    printf("/nHit Return to Exit/n");
    charptr = gets((char *)error);
    exit(1);
  }


  /* Allocate the Connection handle */
  rc = SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hDbc);
  if (rc != SQL_SUCCESS)
  {
    printf("Cannot Allocate Connection Handle/n");
    printf("/nHit Return to Exit/n");
    charptr = gets((char*) error);
    exit(1);
  }

  /* Get User Information */
  lstrcpy((char*) pUserName, DefUserName);
  lstrcpy((char*) pPassWord, DefPassWord);

  /* Data Source name */
  printf( "/nEnter the ODBC Data Source Name/n" );
  charptr = gets((char*) ServerName);

  /* User Name */
  printf("/nEnter User Name Default [%s]/n", pUserName);
  charptr = gets((char*) UserName);
  if (*charptr == '/0')
  {
    lstrcpy((char*) pUserName, (char*) DefUserName);
  }

  /* Password */
  printf ("/nEnter Password Default [%s]/n", pPassWord);
  charptr = gets((char*) PassWord);
  if (*charptr == '/0')
  {
    lstrcpy((char*) pPassWord, (char*) DefPassWord);
  }

  /* Connection to the database */
  rc = SQLConnect(hDbc, pServerName, (SQLSMALLINT) lstrlen((char *)pServerName), pUserName,
                  (SQLSMALLINT) lstrlen((char*)pUserName), pPassWord,
                  (SQLSMALLINT) lstrlen((char *)pPassWord));
  if (rc != SQL_SUCCESS)
  {
    DisplayError(SQL_HANDLE_DBC, hDbc, "SQLConnect");
  }
 
  /* Allocate a Statement */
  rc = SQLAllocHandle(SQL_HANDLE_STMT, hDbc, &hStmt);
  if (rc != SQL_SUCCESS)
  {
    printf( "Cannot Allocate Statement Handle/n");
    printf( "/nHit Return to Exit/n");
    charptr = gets((char *)error);
    exit(1);
  }

  /* Drop the Package */
  lstrcpy((char *) pSqlStmt, "DROP PACKAGE ODBCRefCur");
  rc = SQLExecDirect(hStmt, pSqlStmt, lstrlen((char *)pSqlStmt));

  /* Create the Package Header */
  lstrcpy((char *) pSqlStmt, "CREATE PACKAGE ODBCRefCur AS/n" );
  lstrcat((char *) pSqlStmt, " TYPE ename_cur IS REF CURSOR;/n" );
  lstrcat((char *) pSqlStmt, " TYPE mgr_cur IS REF CURSOR;/n" );
  lstrcat((char *) pSqlStmt, " PROCEDURE EmpCurs (Ename IN OUT ename_cur," );
  lstrcat((char *) pSqlStmt, " Mgr IN OUT mgr_cur,pjob IN VARCHAR2);/n/n");
  lstrcat((char *) pSqlStmt, "END;/n" );

  rc = SQLExecDirect(hStmt, pSqlStmt, lstrlen((char *)pSqlStmt));
  if (rc != SQL_SUCCESS)
  {
    DisplayError(SQL_HANDLE_STMT, hStmt, "SQLExecDirect");
  }

  /* Create the Package Body */
  lstrcpy((char *) pSqlStmt, "CREATE PACKAGE BODY ODBCRefCur AS/n" );
  lstrcat((char *) pSqlStmt, " PROCEDURE EmpCurs (Ename IN OUT ename_cur," );
  lstrcat((char *) pSqlStmt, " Mgr IN OUT mgr_cur, pjob IN VARCHAR2)/n" );
  lstrcat((char *) pSqlStmt, " AS/n" );
  lstrcat((char *) pSqlStmt, " BEGIN/n" );
  lstrcat((char *) pSqlStmt, " IF NOT Ename%ISOPEN/n" );
  lstrcat((char *) pSqlStmt, " THEN/n" );
  lstrcat((char *) pSqlStmt, " OPEN Ename for SELECT ename from emp;/n" );
  lstrcat((char *) pSqlStmt, " END IF;/n/n" );
  lstrcat((char *) pSqlStmt, " IF NOT Mgr%ISOPEN/n THEN/n" );
  lstrcat((char *) pSqlStmt, " OPEN Mgr for SELECT mgr from emp where job = pjob;/n");
  lstrcat((char *) pSqlStmt, " END IF;/n" );
  lstrcat((char *) pSqlStmt, " END;/n" );


  lstrcat((char *) pSqlStmt, "END;/n" );

  rc = SQLExecDirect(hStmt, pSqlStmt, lstrlen((char *)pSqlStmt));
  if(rc != SQL_SUCCESS)
    DisplayError(SQL_HANDLE_STMT, hStmt, "SQLExecDirect");

  /* Bind the Parameter */
  rc = SQLBindParameter(hStmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, JOB_LEN, 0, pSalesMan, 0, &sqlnts);

  /* Call the Store Procedure which executes the Result Sets */
  lstrcpy( (char *) pSqlStmt, "{CALL ODBCRefCur.EmpCurs(?)}");

  rc = SQLExecDirect(hStmt, pSqlStmt, lstrlen((char *)pSqlStmt));
  if(rc != SQL_SUCCESS)
    DisplayError(SQL_HANDLE_STMT, hStmt, "SQLExecDirect");

  /* Bind the Data */
  rc = SQLBindCol(hStmt, 1, SQL_C_CHAR, Data, sizeof(Data), &DataLen);
  if(rc != SQL_SUCCESS)
    DisplayError(SQL_HANDLE_STMT, hStmt, "SQLBindCol");
 
  /* Get the data for Result Set 1 */
  printf("/nEmployee Names/n/n");

  while(rc == SQL_SUCCESS)
  {
    rc = SQLFetch(hStmt);
    if(rc == SQL_SUCCESS)
      printf("%s/n", Data);
    else
      if(rc != SQL_NO_DATA)
        DisplayError(SQL_HANDLE_STMT, hStmt, "SQLFetch");
  }

  printf( "/nFirst Result Set - Hit Return to Continue/n");
  charptr = gets ((char *)error);

  /* Get the Next Result Set */
  rc = SQLMoreResults( hStmt );
  if(rc != SQL_SUCCESS)
    DisplayError(SQL_HANDLE_STMT, hStmt, "SQLMoreResults");

  /* Get the data for Result Set 2 */
  printf("/nManagers/n/n");
  while (rc == SQL_SUCCESS)
  {
    rc = SQLFetch(hStmt);
    if(rc == SQL_SUCCESS)
      printf("%s/n", Data);
    else
      if (rc != SQL_NO_DATA)
        DisplayError(SQL_HANDLE_STMT, hStmt, "SQLFetch");
  }

  printf("/nSecond Result Set - Hit Return to Continue/n");
  charptr = gets((char *)error);

  /* Should Be No More Results Sets */
  rc = SQLMoreResults( hStmt );
  if (rc != SQL_NO_DATA)
    DisplayError(SQL_HANDLE_STMT, hStmt, "SQLMoreResults");

  /* Drop the Package */
  lstrcpy((char *)pSqlStmt, "DROP PACKAGE ODBCRefCur");
  rc = SQLExecDirect(hStmt, pSqlStmt, lstrlen((char *)pSqlStmt));

  /* Free handles close connections to the database */
  SQLFreeHandle( SQL_HANDLE_STMT, hStmt );
  SQLDisconnect( hDbc );
  SQLFreeHandle( SQL_HANDLE_DBC, hDbc );
  SQLFreeHandle( SQL_HANDLE_ENV, hEnv );

  printf( "/nAll Done - Hit Return to Exit/n");
  charptr = gets ((char *)error);
  return(0);
}
 
/* Display Error Messages */
void DisplayError( SWORD HandleType, SQLHANDLE hHandle, char *Module )
{
  SQLCHAR MessageText[255];
  SQLCHAR SQLState[80];
  SQLRETURN rc=SQL_SUCCESS;
  LONG NativeError;
  SWORD RetLen;
  SQLCHAR error[25];
  char *charptr;

  rc = SQLGetDiagRec(HandleType, hHandle, 1, SQLState, &NativeError, MessageText, 255, &RetLen);
  printf( "Failure Calling %s/n", Module );
  if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO)
  {
    printf( "/t/t/t State: %s/n", SQLState);
    printf( "/t/t/t Native Error: %d/n", NativeError );
    printf( "/t/t/t Error Message: %s/n", MessageText );
  }

  printf( "/nHit Return to Exit/n");
  charptr = gets ((char *)error);
  exit(1);
}

EXEC構文の有効化

このオプションを有効にすると、変更なしに変換可能な場合、Oracle ODBC Driverによって、SQL Server EXEC文の構文が対応するOracleプロシージャ・コールに変換されます。

SQL Serverプロシージャの完全な名前は、次に示す最大4つの識別子で構成されます。

  • サーバー名

  • データベース名

  • 所有者名

  • プロシージャ名

この名前の書式は次のとおりです。

[[[server.][database].][owner_name].]procedure_name

SQL ServerデータベースからOracleへの移行時、それぞれのSQL Serverプロシージャ(またはファンクション)定義は、対応するOracle構文に変換され、Oracleスキーマに定義されます。移行したプロシージャは、多くの場合、次のいずれかの方法で再編成(およびスキーマで作成)されます。

  • すべてのプロシージャが1つのスキーマに移行されます(デフォルト・オプション)。

  • 1つのSQL Serverデータベースに定義されているすべてのプロシージャが、そのデータベース名の付いたスキーマに移行されます。

  • 特定のユーザーが所有するすべてのプロシージャが、そのユーザー名の付いたスキーマに移行されます。

移行したプロシージャを編成するこれら3通りの方法をサポートするためには、いずれかのスキーマ名オプションを指定してプロシージャ名を変換できます。変換したOracleプロシージャ・コールのオブジェクト名では、大/小文字が区別されません。

Oracle RAC環境における接続障害のイベント通知の有効化

Oracle Real Application Clusters (Oracle RAC)データベース環境で接続障害が発生したときに、 SQLSetConnectAttr関数のSQL_ORCLATTR_FAILOVER_CALLBACKおよびSQL_ORCLATTR_FAILOVER_HANDLE属性が設定されている場合、イベント通知が有効になります。どちらの属性も、SQLSetConnectAttr関数を使用して設定されます。新規属性のシンボルは、ファイルsqora.hで定義されています。

SQL_ORCLATTR_FAILOVER_CALLBACK属性は、障害イベントが発生したときにコールするルーチンのアドレスを指定します。

SQL_ORCLATTR_FAILOVER_HANDLE属性は、コールバック・ルーチンのパラメータとして渡されるコンテキスト・ハンドルを指定します。この属性は、ODBCアプリケーションで障害イベントが発生している接続を判別するために必要です。

コールバック・ルーチンの関数プロトタイプは次のとおりです。

void failover_callback(void *handle, SQLINTEGER fo_code)

'handle'パラメータは、SQL_ORCLATTR_FAILOVER_HANDLE属性により設定された値です。この属性が設定されていない場合、NULLが戻されます。

fo_codeパラメータにより、発生している障害イベントが識別されます。障害イベントは、OCIプログラミング・インタフェースで定義されているイベントに直接マップされます。発生する可能性があるイベントのリストを次に示します。

  • ODBC_FO_BEGIN

  • ODBC_FO_ERROR

  • ODBC_FO_ABORT

  • ODBC_FO_REAUTH

  • ODBC_FO_END

この機能の使用方法を示したサンプル・プログラムは次のとおりです。

/*
  NAME
  ODBCCallbackTest
 
  DESCRIPTION
  Simple program to demonstrate the connection failover callback feature.
 
  PUBLIC FUNCTION(S)
  main
 
  PRIVATE FUNCTION(S)
 
  NOTES
 
  Command Line: ODBCCallbackTest filename [odbc-driver]
 
*/
 
#include <windows.h>
#include <tchar.h>
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include <sql.h>
#include <sqlext.h>
#include "sqora.h"
 
/*
** Function Prototypes
*/
void display_errors(SQLSMALLINT HandleType, SQLHANDLE Handle);
void failover_callback(void *Handle, SQLINTEGER fo_code);
 
/*
** Macros
*/
#define ODBC_STS_CHECK(sts) \
  if (sts != SQL_SUCCESS) \
{ \
  display_errors(SQL_HANDLE_ENV, hEnv); \
  display_errors(SQL_HANDLE_DBC, hDbc); \
  display_errors(SQL_HANDLE_STMT, hStmt); \
  return FALSE; \
}
 
/*
** ODBC Handles
*/
SQLHENV *hEnv = NULL; // ODBC Environment Handle
SQLHANDLE *hDbc = NULL; // ODBC Connection Handle
SQLHANDLE *hStmt = NULL; // ODBC Statement Handle
 
/*
** Connection Information
*/
TCHAR *dsn = _T("odbctest");
TCHAR *uid = _T("scott");
TCHAR *pwd = _T("tiger");
TCHAR *szSelect = _T("select * from emp");
 
/*
** MAIN Routine
*/
main(int argc, char **argv)
{
  SQLRETURN rc;
 
  /*
  ** Allocate handles
  */
  rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, (SQLHANDLE *)&hEnv);
  ODBC_STS_CHECK(rc)
 
  rc = SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0);
  ODBC_STS_CHECK(rc);
 
  rc = SQLAllocHandle(SQL_HANDLE_DBC, hEnv, (SQLHANDLE *)&hDbc);
  ODBC_STS_CHECK(rc);
 
  /*
  ** Connect to the database
  */
  rc = SQLConnect(hDbc, dsn, (SQLSMALLINT)_tcslen(dsn),
  uid, (SQLSMALLINT)_tcslen(uid),
  pwd, (SQLSMALLINT)_tcslen(pwd));
  ODBC_STS_CHECK(rc);
 
  /*
  ** Set the connection failover attributes
  */
  rc = SQLSetConnectAttr(hDbc, SQL_ORCLATTR_FAILOVER_CALLBACK, &failover_callback, 0);
  ODBC_STS_CHECK(rc);
 
  rc = SQLSetConnectAttr(hDbc, SQL_ORCLATTR_FAILOVER_HANDLE, hDbc, 0);
  ODBC_STS_CHECK(rc);
 
  /*
  ** Allocate the statement handle
  */
  rc = SQLAllocHandle(SQL_HANDLE_STMT, hDbc, (SQLHANDLE *)&hStmt);
  ODBC_STS_CHECK(rc);
 
  /*
  ** Wait for connection failovers
  */
   while (TRUE)
  {
   Sleep(5000);
   rc = SQLExecDirect(hStmt,szSelect, _tcslen(szSelect));
   ODBC_STS_CHECK(rc);
 
   rc = SQLFreeStmt(hStmt, SQL_CLOSE);
   ODBC_STS_CHECK(rc);
  }
 
  /*
  ** Free up the handles and close the connection
  */
  rc = SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
  ODBC_STS_CHECK(rc);
 
  rc = SQLDisconnect(hDbc);
  ODBC_STS_CHECK(rc);
 
  rc = SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
  ODBC_STS_CHECK(rc);
 
  rc = SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
  ODBC_STS_CHECK(rc);
 
  return TRUE;
}
 
/*
** Failover Callback Routine
*/
void failover_callback(void *Handle, SQLINTEGER fo_code)
{
  switch(fo_code)
  {
  case ODBC_FO_BEGIN:
    printf("ODBC_FO_BEGIN recevied\n");
    break;
   
  case ODBC_FO_ERROR:
    printf("ODBC_FO_ERROR recevied\n");
    break;
  
  case ODBC_FO_ABORT:
    printf("ODBC_FO_ABORT recevied\n");
    break;
  
  case ODBC_FO_REAUTH:
    printf("ODBC_FO_REAUTH recevied\n");
    break;
  
  case ODBC_FO_END:
    printf("ODBC_FO_END recevied\n");
    break;
  
  default:
    printf("Invalid or unknown ODBC failover code recevied\n");
    break;
  } 
  return;
 
}
 
/*
** Retrieve the errors associated with the handle passed
** and display them.
*/
void display_errors(SQLSMALLINT HandleType, SQLHANDLE Handle)
{
  SQLTCHAR MessageText[256];
  SQLTCHAR SqlState[5+1];
  SQLSMALLINT i=1;
  SQLINTEGER NativeError;
  SQLSMALLINT TextLength;
  SQLRETURN sts = SQL_SUCCESS;
 
  if (Handle == NULL) return;
 
  /* Make sure all SQLState text is null terminated */
  SqlState[5] = '\0';
 
  /*
  ** Fetch and display all diagnostic records that exist for this handle
  */
  while (sts == SQL_SUCCESS)
  {
    NativeError = 0;
    TextLength = 0;

    sts = SQLGetDiagRec(HandleType, Handle, i, SqlState, &NativeError, (SQLTCHAR *)&MessageText, sizeof(MessageText), &TextLength);
    if (sts == SQL_SUCCESS)
    {
      printf("[%s]%s\n", SqlState, MessageText);
      if (NativeError != 0)
        printf("Native Error Code: %d\n", NativeError);
      i++;
    }
  } 
  return;
}

ODBCを通じた暗黙的結果機能の使用

このオプションは、サード・パーティODBCアプリケーションをOracleデータベースに移行し、前のベンダーでサポートされている暗黙的結果機能を使用する場合に使用します。Oracle ODBC Driverでは、ストアド・プロシージャまたは匿名PL/SQLブロックでの暗黙的結果がサポートされます。現在のリリースでは、暗黙的結果はSELECT文でのみ戻されます。

次のコード例は、暗黙的結果に匿名SQLスクリプトを使用したODBCテスト・ケースの例を示しています。

const char *query1="declare \
                  c1 sys_refcursor; \
                  c2 sys_refcursor; \
                  begin \
                  open c1 for select empno,ename from emp where rownum<=3; \
                  dbms_sql.return_result(c1); \
                  open c2 for select empno,ename from emp where rownum<=3; \
                  dbms_sql.return_result(c2); end; ";
 
int main( )
{
  ...
   ...
 //Allocate all required handles and establish a connection to the database.
 
 //Prepare and execute the above anonymous PL/SQL block
    SQLPrepare (hstmt, (SQLCHAR *) query1, SQL_NTS);
    SQLExecute(hstmt);
 
 //Bind the columns for the results from the first SELECT statement in an anonymous block.
    SQLBindCol (hstmt, 1, SQL_C_ULONG, &eno, 0, &jind);
    SQLBindCol (hstmt, 2, SQL_C_CHAR, empname, sizeof (empname),&enind);
 
 //Fetch implicit results through the SQLFetch( ) call.
    while((retCode = SQLFetch(hstmt)) != SQL_NO_DATA)
    {
 //Do whatever you want to do with the data.
    }
 
     retCode = SQLMoreResults(hstmt);
 
     if(retCode == SQL_SUCCESS)
    {
      printf("SQLMoreResults returned with SQL_SUCCESS\n");
 
 //Bind the columns for the results from the second SELECT statement in an anonymous block.
    SQLBindCol (hstmt, 1, SQL_C_ULONG, &eno, 0, &jind);
    SQLBindCol (hstmt, 2, SQL_C_CHAR, empname, sizeof (empname),&enind);
 
 //Fetch implicit results through the SQLFetch( ) call.
    while((retCode = SQLFetch(hstmt)) != SQL_NO_DATA)
    {
 //Do whatever you want to do with data.
    }
  }
}

ODBCでのOracle TIMESTAMP WITH TIME ZONEおよびTIMESTAMP WITH LOCAL TIME ZONE列タイプのサポートの概要

タイムゾーンはシステム変数ORA_SDTZに定められています。システム変数を'OS_TZ''DB_TZ'または有効なタイム・ゾーン値に設定できます。ORA_SDTZ'OS_TZ'に設定すると、オペレーティング・システムのタイムゾーンが使用されます。'DB_TZ'に設定した場合は、データベースに設定されたデフォルトのタイムゾーンが使用されます。

ORA_SDTZが設定されていない場合は、デフォルトでオペレーティング・システムのタイムゾーンが使用されます。

注意:

Microsoft Windows環境のレジストリ、システム環境変数またはコマンド・プロンプト・ウィンドウでORA_SDTZ変数を設定する場合、タイム・ゾーン値を引用符で囲まないでください。

関連項目:

日時データ型およびタイム・ゾーン・サポートの詳細は、Oracle Databaseグローバリゼーション・サポート・ガイドを参照

ODBCデータ型TIMESTAMP_STRUCTの変数を使用したこれらのタイムゾーン列からのデータのフェッチ

次の例では、ODBCデータ型TIMESTAMP_STRUCTの変数を使用して、TIMESTAMP WITH TIME ZONE列およびTIMESTAMP WITH LOCAL TIME ZONE列からデータをフェッチする方法を示します。

例24-1 ODBCデータ型TIMESTAMP_STRUCTの変数を使用してTIMESTAMP WITH TIME ZONE列およびTIMESTAMP WITH LOCAL TIME ZONE列からデータをフェッチする方法

int main() 
{ 
... 
...  
 /* TSTAB table's DDL statement:  
  * ---------------------------  
  * CREATE TABLE TSTAB (COL_TSTZ  TIMESTAMP WITH TIME ZONE,  
  *                     COL_TSLTZ TIMESTAMP WITH LOCAL TIME ZONE);  
  *  
  * Insert statement:  
  * ----------------  
  * Sample #1:  
  * ---------  
  * INSERT INTO TSTAB VALUES (TIMESTAMP '2010-03-13 03:47:30.123456 America/Los_Angeles'  
  *                           TIMESTAMP '2010-04-14 04:47:30.123456 America/Los_Angeles');  
  *  
  * Sample #2:  
  * ---------  
  * INSERT INTO TSTAB VALUES ('22-NOV-1963 12:30:00.000000 PM',  
  *                           '24-NOV-1974 02:30:00.000000 PM');  
  *  
  * Refer Oracle Database documentations to know more details about TIMESTAMP  
  * WITH TIME ZONE and TIMESTAMP WITH LOCAL TIME ZONE columns.  
  */   
 SQLCHAR sqlSelQuery[] = "SELECT COL_TSTZ, COL_TSLTZ FROM TSTAB";   
 TIMESTAMP_STRUCT timestampcol1;   
 TIMESTAMP_STRUCT timestampcol2; 
... 
...  
  /* Allocate the ODBC statement handle. */ 
  SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);  

  /* Execute the statement sqlSelQuery. */ 
  SQLExecDirect(hstmt, sqlSelQuery, SQL_NTS); 
 
  /* Bind the variable to read the value from the TIMESTAMP WITH TIME ZONE column. */ 
  SQLBindCol(hstmt, 1, SQL_C_TIMESTAMP, &timestampcol1, sizeof(timestampcol1), NULL); 
 
  /* Bind the variable to read the value from the TIMESTAMP WITH LOCAL TIME ZONE column. */ 
  SQLBindCol(hstmt, 2, SQL_C_TIMESTAMP, &timestampcol2, sizeof(timestampcol2), NULL); 
... 
... 
  /* Fetch data from the TSTAB table. */ 
  retcode = SQLFetch(hstmt);  
  /* Values of column COL_TSTZ and COL_TSLTZ are available in variables  
  * timestampcol1 and timestampcol2 respectively. Refer to Microsoft ODBC  
  * documentation for more information about data type TIMESTAMP_STRUCT. */ 

... 
... 
  /* Close the statement. */ 
  SQLFreeStmt(hstmt, SQL_CLOSE); 
  /* Free the statement handle. */ 
  SQLFreeHandle(SQL_HANDLE_STMT, hstmt); ... ... }

例24-2 TIMESTAMP WITH TIME ZONE列およびTIMESTAMP WITH LOCAL TIME ZONE列にデータを挿入する方法

int main() 
{ 
... 
...   
 SQLCHAR sqlInsQuery[]   = "INSERT INTO TSTAB VALUES (?, ?)";   
 TIMESTAMP_STRUCT timestampcol1;   
 TIMESTAMP_STRUCT timestampcol2; 
... 
...  
 /* Input the value for column COL_TSTZ in table TSTAB. */ 
  timestampcol1.year = 2000; 
  timestampcol1.month = 1; 
  timestampcol1.day   = 1; 
  timestampcol1.hour  = 0; 
  timestampcol1.minute = 0;
  timestampcol1.second = 1; 
  timestampcol1.fraction = 1000; 
 
 /* Input the value for column COL_TSLTZ in table TSTAB. */ 
  timestampcol1.year = 2012; 
  timestampcol1.month = 2; 
  timestampcol1.day   = 5; 
  timestampcol1.hour  = 10; 
  timestampcol1.minute = 30; 
  timestampcol1.second = 10; 
  timestampcol1.fraction = 1000; 
... 
... 
  /* Allocate the ODBC statement handle. */ 
  SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); 
... 
... 
  /* Bind the input value for column COL_TSTZ. */ 
  SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_TIMESTAMP, SQL_TIMESTAMP,   
    0, 0, &timestampcol1, sizeof(timestampcol1), NULL);
  
  /* Bind the input value for column COL_TSLTZ. */ 
  SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_TIMESTAMP, SQL_TIMESTAMP,  
    0, 0, &timestampcol2, sizeof(timestampcol2), NULL); 
... 
... 
  /* Execute the statement sqlInsQuery. */ 
  SQLExecDirect(hstmt, sqlInsQuery, SQL_NTS);
  
  /* Close the statement. */ 
  SQLFreeStmt(hstmt, SQL_CLOSE); 
  /* Free the statement handle. */ 
  SQLFreeHandle(SQL_HANDLE_STMT, hstmt); 
... 
... 
}

Oracleクライアント(OCI、SQL*Plus、Oracle ODBC Driverなど)でORA_SDTZを設定した場合の影響について

Oracleクライアントでシステム変数ORA_SDTZを設定した場合の影響について説明します。

タイムゾーンはシステム変数ORA_SDTZに定められています。

次の項では、Oracleクライアント(OCI、SQL*Plus、Oracle ODBC Driverなど)でシステム変数ORA_SDTZを設定した場合や設定しなかった場合の影響について説明します。これらの項の例は、インド(GMT+5:30)のタイムゾーンで実行されています。

関連項目:

セッション・タイム・ゾーンの詳細は、『Oracle Databaseグローバリゼーション・サポート・ガイド』を参照してください

環境設定

環境を設定するには、TSLTZ (TIMESTAMP WITH LOCAL TIME ZONE)列のある次の表を作成し、01/01/2016 00:00 GMTの値を次に示すようにTSLTZ列に挿入します。

例24-3 環境の設定方法

次の例では、例を示す後続の項の環境を設定しています。

SQL> create table timezone_demo(col1 TIMESTAMP WITH LOCAL TIME ZONE);

Table created.

SQL> INSERT INTO TIMEZONE_DEMO VALUES(TIMESTAMP '2016-01-01 00:00:00.000000 ETC/GREENWICH');

1 row created.

環境内でORA_SDTZが設定されない場合

環境内でORA_SDTZが設定されない場合は、オペレーティング・システム(OS)のタイムゾーン設定がOracleクライアントのデフォルトのタイムゾーンとして使用されます。例:

例24-4 ORA_SDTZが設定されない場合

C:\Users\example.ORADEV>set ORA_SDTZ=

C:\Users\example.ORADEV>sqlplus scott/password@//host01.example.com:1521/ORCL12C1

SQL*Plus: Release 12.1.0.2.0 Production on Fri Apr 22 12:03:52 2016

Copyright (c) 1982, 2014, Oracle. All rights reserved.

Last Successful login time: Fri Apr 22 2016 11:47:12 +05:30

Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options

SQL> select sessiontimezone from dual;

SESSIONTIMEZONE
---------------------------------------------------------------------------
+05:30

SQL> select * from timezone_demo;

COL1
---------------------------------------------------------------------------
01-JAN-16 05.30.00.000000 AM

環境内でORA_SDTZをオペレーティング・システム(OS)のタイムゾーンに設定する場合

ORA_SDTZがオペレーティング・システム(OS)・タイム・ゾーンに設定されている場合、Oracleクライアントのユーザー・セッションはOSタイム・ゾーン設定に設定されます。環境で設定を解除するか、ORA_SDTZOS_TZに設定できます。例:

例24-5 ORA_SDTZがオペレーティング・システム(OS)のタイムゾーンに設定される場合

C:\Users\example.ORADEV>set ORA_SDTZ=OS_TZ

C:\Users\example.ORADEV>sqlplus scott/password@//host01.example.com:1521/ORCL12C1

SQL*Plus: Release 12.1.0.2.0 Production on Fri Apr 22 11:42:36 2016

Copyright (c) 1982, 2014, Oracle. All rights reserved.

Last Successful login time: Fri Apr 22 2016 11:42:09 +05:30

Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options

SQL> select sessiontimezone from dual;

SESSIONTIMEZONE
---------------------------------------------------------------------------
+05:30

SQL> select * from timezone_demo;

COL1
---------------------------------------------------------------------------
01-JAN-16 05.30.00.000000 AM

環境内でORA_SDTZを特定のタイムゾーンに設定する場合

Oracleクライアントは、特定のタイム・ゾーン(たとえば、ヘルシンキ・タイムゾーン)に調整されたタイム・スタンプ値を取得するように設定できます。これを行うには、次を設定します
ORA_SDTZ
対象: 対応するタイムゾーンのOracleタイムゾーンのリージョン名(ヘルシンキのタイムゾーンのOracleタイムゾーンのリージョン名はEurope/Helsinki)。例:

例24-6 ORA_SDTZが特定のタイムゾーンに設定される場合

C:\Users\example.ORADEV>set ORA_SDTZ=Europe/Helsinki

C:\Users\example.ORADEV>sqlplus scott/password@//host01.example.com:1521/ORCL12C1

SQL*Plus: Release 12.1.0.2.0 Production on Fri Apr 22 11:47:10 2016

Copyright (c) 1982, 2014, Oracle. All rights reserved.

Last Successful login time: Fri Apr 22 2016 09:16:18 EUROPE/HELSINKI EEST

Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
SQL> select sessiontimezone from dual;

SESSIONTIMEZONE
---------------------------------------------------------------------------
Europe/Helsinki

SQL> select * from timezone_demo;

COL1
---------------------------------------------------------------------------
01-JAN-16 02.00.00.000000 AM

サポートされている機能

トピック:

APIへの準拠

Oracle ODBC Driverのリリース9.2.0.0.0以降では、すべてのコア、レベル2およびレベル1関数をサポートしています。

また、Oracle ODBC Driverのリリース9.2.0.0.0以降では、変換DLLをサポートしています。

次のトピックでは、Oracle ODBC Driverで実装されているODBC API関数について説明します。

関連項目:

ODBC API関数の実装

次の表は、Oracle ODBC Driverが関数を実装する方法を示したものです。

表24-6 Oracle ODBC Driverで特定の関数を実装する方法

関数 説明:

SQLConnect

SQLConnectには、DBQ、ユーザーIDおよびパスワードのみが必要です。

SQLDriverConnect

SQLDriverConnectは、DSN、DBQ、UIDおよびPWDキーワードを使用します。

SQLMoreResults

暗黙的結果のODBCサポートを実装します。これは、Oracle Database 12cリリース1 (12.1.0.1)に実装されている新しいAPIです。詳細は、SQLMoreResults関数を参照してください。

SQLSpecialColumns

SQLSpecialColumnsは、SQL_BEST_ROWID属性を指定してコールされると、ROWID列を戻します。

SQLProceduresおよびSQLProcedureColumns

次の項を参照してください。

すべてのカタログ関数

SQL_ATTR_METADATA_ID文属性がSQL_TRUEである場合、文字列引数は識別子引数として扱われ、大/小文字の区別はされません。この場合、アンダースコア(_)およびパーセント記号(%)は検索用パターン文字ではなく、実際の文字として処理されます。この属性がSQL_FALSEである場合、通常の引数またはパターン値の引数となり文字どおりに扱われ、大/小文字は区別されます。

ODBC SQL構文の実装

比較述語で比較の2番目の式としてパラメータ・マーカーが使用され、そのパラメータの値がSQLBindParameterを使用してSQL_NULL_DATAに設定されている場合、比較は失敗します。これは、ODBC SQLのNULL述語構文と一致しています。

データ型の実装(プログラミング)

プログラマにとって特に注意が必要なのは、CHARVARCHARおよびVARCHAR2データ型の実装です。

SQL_VARCHARの値がfSqlTypeの場合、SQLGetTypeInfoはOracle Databaseデータ型VARCHAR2を返します。また、SQLGetTypeInfoは、SQL_CHARのfSqlType値に対しては、Oracleデータベース・データ型であるCHARを戻します。

Unicodeのサポート

トピック:

ODBC環境内のUnicodeサポート

MicrosoftまたはunixODBC ODBCドライバ・マネージャ(ドライバ・マネージャ)によって、Unicodeをサポートしているかどうかに関係なく、すべてのODBCドライバがUnicode対応しているように動作します。これによって、ODBCアプリケーションは、基礎となるODBCドライバのUnicode機能に関係なく記述できます。

Driver ManagerがANSI ODBCドライバに対するUnicodeサポートをエミュレートできる範囲は、Unicodeデータとローカル・コード・ページ間で可能な変換内容によって制限されます。Driver ManagerがデータをUnicodeからローカル・コード・ページに変換する際、データが失われる場合があります。基礎となるODBCドライバがUnicodeをサポートしていないかぎり、Unicodeの完全なサポートは不可能です。Oracle ODBC DriverはUnicodeをフル・サポートしています。

ODBC API内でのUnicodeサポート

ODBC APIは、"W"と"A"という決まった接尾辞によって、UnicodeおよびANSIエントリ・ポイントの両方をサポートします。ODBCアプリケーション開発者は、接尾辞を指定してエントリ・ポイントを明示的にコールする必要はありません。UNICODEおよび_UNICODEプリプロセッサ定義を使用してコンパイルされたODBCアプリケーションによって、適切なコールが生成されます。たとえば、SQLPrepareコールはSQLPrepareWとしてコンパイルされます。

Cデータ型のSQL_C_WCHARがODBCインタフェースに追加されたため、アプリケーションでは、入力パラメータをUnicodeとしてエンコードするように指定するか、またはUnicodeとして返された列データを要求できます。マクロのSQL_C_TCHARは、UnicodeおよびANSIの両方で作成する必要があるアプリケーションで有効です。SQL_C_TCHARマクロは、Unicodeアプリケーションの場合はSQL_C_WCHARとして、ANSIアプリケーションの場合はSQL_C_CHARとしてコンパイルされます。

SQLデータ型のSQL_WCHARSQL_WVARCHARおよびSQL_WLONGVARCHARがODBCインタフェースに追加され、表内で定義された列がUnicodeで表現されるようになりました。これらの値は、SQLDescribeColSQLColAttributeSQLColumnsおよびSQLProcedureColumnsへのコールから返すことも可能です。

Unicodeエンコードは、SQL列型NCHARNVARCHAR2およびNCLOBについてサポートされています。また、SQL列型CHARおよびVARCHAR2についても、キャラクタ・セマンティクスが列定義で指定されている場合は、Unicodeエンコードがサポートされます。

Oracle ODBC DriverはこれらのSQL列型をサポートしており、これらをODBC SQLデータ型にマップします。

次の表に、サポートされているSQLデータ型および対応するODBC SQLデータ型を示します。

表24-7 サポートされるSQLデータ型および対応するODBC SQLデータ型

SQLデータ型 ODBC SQLデータ型

CHAR

SQL_CHARまたはSQL_WCHAR 脚注1

VARCHAR2

SQL_VARCHARまたはSQL_WVARCHAR 脚注2

NCHAR

SQL_WCHAR

NVARCHAR2

SQL_WVARCHAR

NCLOB

SQL_WLONGVARCHAR

脚注1

キャラクタ・セマンティクスが列定義で指定されている場合およびデータベースのキャラクタセットがUnicodeの場合、CHARSQL_WCHARにマップされます。

脚注2

キャラクタ・セマンティクスが列定義で指定されている場合およびデータベースのキャラクタセットがUnicodeの場合、VARCHAR2SQL_WVARCHARにマップされます。

ドライバ・マネージャのUnicode機能

ドライバ・マネージャは、ODBCドライバがUnicodeをサポートしていないことを検出すると、次を実行します。

  • ANSI ODBCドライバをコールする前にUnicode用関数コールをANSI用関数コールに変換します。文字列引数はUnicodeからローカル・コード・ページに変換されます。たとえば、SQLPrepareWコールはSQLPrepareコールに変換されます。SQL文パラメータの文字列はUnicodeからローカル・コード・ページに変換されます。

  • 文字データのリターン・パラメータを、ローカル・コード・ページからUnicodeに変換します。たとえば、SQLColAttributeを使用して列名を戻す場合です。

  • SQL_C_WCHARでバインドされた列に対し、データをローカル・コード・ページからUnicodeコード・ページに変換します。

  • SQL_C_WCHARでバインドされた入力パラメータに対し、データをUnicodeからローカル・コード・ページに変換します。

SQLGetDataのパフォーマンス

SQLGetData関数を使用すると、ODBCアプリケーションはデータ型を指定して、データのフェッチ後に列を取得できます。OCIでは、Oracle ODBC Driverがフェッチ前にデータ型を指定する必要があります。OCIの場合、Oracle ODBC Driverは、データベース内で定義されている列のデータ型の情報を使用し、OCI経由で列データをフェッチする最適な方法を決定します。

文字データを含む列がSQLBindColによってバインドされていない場合、Oracle ODBC Driverは、その列をUnicodeとしてフェッチするか、またはローカル・コード・ページとしてフェッチするかを判断する必要があります。ドライバは、デフォルトとして列をUnicodeで受け取ることが可能ですが、結果として不要な変換を2回行うことになります。たとえば、データベースでデータがANSIでエンコードされている場合、Oracle ODBC Driverにデータを送る際にANSIからUnicodeへ変換されるとします。ODBCアプリケーションがSQL_C_CHARとしてデータを要求すると、元のエンコーディングに戻すために、さらに変換が行われることになります。

データのフェッチでは、Oracleクライアントのデフォルトのエンコーディングが使用されます。ODBCアプリケーションでは、WCHARデータ型として列またはパラメータをバインドすることにより、このデフォルトを上書きして、Unicodeとしてデータをフェッチすることができます。

Unicodeの例

Oracle ODBC Driver自体がTCHARマクロを使用して実装されているため、ODBCアプリケーション・プログラムでドライバを活用するためにTCHARを使用することをお薦めします。

次のプログラムではTCHARの使用方法を示します。TCHARはUNICODEおよび_UNICODEを指定してコンパイルする場合は、WCHARデータ型になります。

例1 データベースへの接続

SQLConnectに対してUnicodeリテラルを使用する以外、他との違いはありません。

SQLHENV envHnd;
SQLHDBC conHnd;
SQLHSTMT stmtHnd;
RETCODE rc;

rc = SQL_SUCCESS;

// ENV is allocated
rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &envHnd);
// Connection Handle is allocated
rc = SQLAllocHandle(SQL_HANDLE_DBC, envHnd, &conHnd);
rc = SQLConnect(conHnd, _T("stpc19"), SQL_NTS, _T("scott"), SQL_NTS, _T("tiger"),
 SQL_NTS);
.
.
.
if (conHnd)
{
  SQLDisconnect(conHnd);
  SQLFreeHandle(SQL_HANDLE_DBC, conHnd);
}
if (envHnd)
  SQLFreeHandle(SQL_HANDLE_ENV, envHnd);

例2 単純なデータ取出し

次の例では、従業員名と職種をEMP表から取り出します。すべてのODBC関数にTCHAR準拠のデータを指定する必要があることを除いて、ANSIの場合と違いはありません。Unicodeアプリケーションの場合は、SQLBindColをコールするときにバッファの長さをBYTE長で指定する必要があります(例: sizeof(ename))。

/*
** Execute SQL, bind columns, and Fetch.
** Procedure:
**
** SQLExecDirect
** SQLBindCol
** SQLFetch
**
 */
static SQLTCHAR *sqlStmt = _T("SELECT ename, job FROM emp");
SQLTCHAR ename[50];
SQLTCHAR job[50];
SQLINTEGER enamelen, joblen;
 
_tprintf(_T("Retrieve ENAME and JOB using SQLBindCol 1.../n[%s]/n"), sqlStmt);
 
/* Step 1: Prepare and Execute */
rc = SQLExecDirect(stmtHnd, sqlStmt, SQL_NTS); /* select */
checkSQLErr(envHnd, conHnd, stmtHnd, rc);
 
/* Step 2: Bind Columns */
rc = SQLBindCol(stmtHnd, 1, SQL_C_TCHAR, ename, sizeof(ename), &enamelen);
checkSQLErr(envHnd, conHnd, stmtHnd, rc);
 
rc = SQLBindCol(stmtHnd, 2, SQL_C_TCHAR, job, sizeof(job), &joblen);
checkSQLErr(envHnd, conHnd, stmtHnd, rc);
 
do
{
  /* Step 3: Fetch Data */
  rc = SQLFetch(stmtHnd);
  if (rc == SQL_NO_DATA)
    break;
  checkSQLErr(envHnd, conHnd, stmtHnd, rc);
  _tprintf(_T("ENAME = %s, JOB = %s/n"), ename, job);
} while (1);
_tprintf(_T("Finished Retrieval/n/n"));

例3 SQLGetDataを使用したデータ取出し(フェッチ後のバインド)

この例では、SQLGetDataの使用方法を示します。ODBCプログラミングに精通していない場合は、OCIプログラムの場合と異なり、SQLGetDataを使用することで、データをバインドする前にフェッチすることが可能です。Unicode固有の事項に関しては、ANSIアプリケーションとの違いはありません。

/*
** Execute SQL, bind columns, and Fetch.
** Procedure:
**
** SQLExecDirect
** SQLFetch
** SQLGetData
 */
static SQLTCHAR *sqlStmt = _T("SELECT ename,job FROM emp"); // same as Case 1.
SQLTCHAR ename[50];
SQLTCHAR job[50];
 
_tprintf(_T("Retrieve ENAME and JOB using SQLGetData.../n[%s]/n"), sqlStmt);
if (rc != SQL_SUCCESS)
{
  _tprintf(_T("Failed to allocate STMT/n"));
  goto exit2;
}
 
/* Step 1: Prepare and Execute */
rc = SQLExecDirect(stmtHnd, sqlStmt, SQL_NTS); // select
checkSQLErr(envHnd, conHnd, stmtHnd, rc);

do
{
  /* Step 2: Fetch */
  rc = SQLFetch(stmtHnd);
  if (rc == SQL_NO_DATA)
    break;

  checkSQLErr(envHnd, conHnd, stmtHnd, rc);

  /* Step 3: GetData */
  rc = SQLGetData(stmtHnd, 1, SQL_C_TCHAR, (SQLPOINTER)ename, sizeof(ename), NULL);
  checkSQLErr(envHnd, conHnd, stmtHnd, rc);
  
  rc = SQLGetData(stmtHnd, 2, SQL_C_TCHAR, (SQLPOINTER)job, sizeof(job), NULL);
  checkSQLErr(envHnd, conHnd, stmtHnd, rc);

  _tprintf(_T("ENAME = %s, JOB = %s/n"), ename, job);

} while (1);

_tprintf(_T("Finished Retrieval/n/n"));

例4 単純なデータ更新

この例では、データの更新方法を示します。同様に、SQLBindParameterに対するデータ長は、Unicodeアプリケーションの場合でもBYTE長で指定します。

/
*
** Execute SQL, bind columns, and Fetch.
** Procedure:
**
** SQLPrepare
** SQLBindParameter
** SQLExecute
*/

static SQLTCHAR *sqlStmt = _T("INSERT INTO emp(empno,ename,job) VALUES(?,?,?)");
static SQLTCHAR *empno = _T("9876"); // Emp No
static SQLTCHAR *ename = _T("ORACLE"); // Name
static SQLTCHAR *job = _T("PRESIDENT"); // Job
 
_tprintf(_T("Insert User ORACLE using SQLBindParameter.../n[%s]/n"), sqlStmt);
 
/* Step 1: Prepare */

rc = SQLPrepare(stmtHnd, sqlStmt, SQL_NTS);
checkSQLErr(envHnd, conHnd, stmtHnd, rc);
 
/* Step 2: Bind Parameter */

rc = SQLBindParameter(stmtHnd, 1, SQL_PARAM_INPUT, SQL_C_TCHAR, SQL_DECIMAL,4, 0, (SQLPOINTER)empno, 0, NULL);
checkSQLErr(envHnd, conHnd, stmtHnd, rc);

rc = SQLBindParameter(stmtHnd, 2, SQL_PARAM_INPUT, SQL_C_TCHAR, SQL_CHAR, lstrlen(ename)*sizeof(TCHAR), 0, (SQLPOINTER)ename, lstrlen(ename)*sizeof(TCHAR), NULL);
checkSQLErr(envHnd, conHnd, stmtHnd, rc);
 
rc = SQLBindParameter(stmtHnd, 3, SQL_PARAM_INPUT, SQL_C_TCHAR, SQL_CHAR, lstrlen(job)*sizeof(TCHAR), 0, (SQLPOINTER)job, lstrlen(job)*sizeof(TCHAR), NULL);
checkSQLErr(envHnd, conHnd, stmtHnd, rc);
 
/* Step 3: Execute */

rc = SQLExecute(stmtHnd);
checkSQLErr(envHnd, conHnd, stmtHnd, rc);

例5 LONGデータ(CLOB)の更新と取出し

この例は、OracleのCLOBのような大きなデータの更新と取出しをする、最も複雑な場合の例です。データ長はBYTE長である必要があるため、BYTE長を導出するにはlstrlen(TCHAR data)*sizeof(TCHAR)が必要です。

/*
** Execute SQL, bind columns, and Fetch.
** Procedure:
**
** SQLPrepare
** SQLBindParameter
** SQLExecute
** SQLParamData
** SQLPutData
**
** SQLExecDirect
** SQLFetch
** SQLGetData
 */

static SQLTCHAR *sqlStmt1 = _T("INSERT INTO clobtbl(clob1) VALUES(?)");
static SQLTCHAR *sqlStmt2 = _T("SELECT clob1 FROM clobtbl");
SQLTCHAR clobdata[1001];
SQLTCHAR resultdata[1001];
SQLINTEGER ind = SQL_DATA_AT_EXEC;
SQLTCHAR *bufp;
SQLTCHAR ch;
int clobdatalen, chunksize, dtsize, retchklen, i, len;
 
_tprintf(_T("Insert CLOB1 using SQLPutData.../n[%s]/n"), sqlStmt1);
 
/* Set CLOB Data *

for (i=0, ch=_T('A'); i< sizeof(clobdata)/sizeof(SQLTCHAR); ++i, ++ch)
{
  if (ch > _T('Z'))
  ch = _T('A');
  clobdata[i] = ch;
}

clobdata[sizeof(clobdata)/sizeof(SQLTCHAR)-1] = _T('/0');
clobdatalen = lstrlen(clobdata);
chunksize = clobdatalen / 7;
 
/* Step 1: Prepare */
rc = SQLPrepare(stmtHnd, sqlStmt1, SQL_NTS);
checkSQLErr(envHnd, conHnd, stmtHnd, rc);
 
/* Step 2: Bind Parameter with SQL_DATA_AT_EXEC */
rc = SQLBindParameter(stmtHnd, 1, SQL_PARAM_INPUT, SQL_C_TCHAR, SQL_LONGVARCHAR, clobdatalen*sizeof(TCHAR), 0, (SQLPOINTER)clobdata, clobdatalen*sizeof(TCHAR), &ind);
checkSQLErr(envHnd, conHnd, stmtHnd, rc);
 
/* Step 3: Execute */
rc = SQLExecute(stmtHnd);
checkSQLErr(envHnd, conHnd, stmtHnd, rc);
sdhamoth: Continuation:

 
/* Step 4: ParamData (initiation) */
rc = SQLParamData(stmtHnd, (SQLPOINTER*)&bufp);
checkSQLErr(envHnd, conHnd, stmtHnd, rc);
 
for (dtsize=0, bufp = clobdata; dtsize < clobdatalen; dtsize += chunksize, bufp += chunksize)
{
  if (dtsize+chunksize<clobdatalen)
    len = chunksize;
  else
    len = clobdatalen-dtsize;
 
  /* Step 5: PutData */
  rc = SQLPutData(stmtHnd, (SQLPOINTER)bufp, len*sizeof(TCHAR));
  checkSQLErr(envHnd, conHnd, stmtHnd, rc);
}
 
/* Step 6: ParamData (termination) */
rc = SQLParamData(stmtHnd, (SQLPOINTER*)&bufp);
checkSQLErr(envHnd, conHnd, stmtHnd, rc);
 
rc = SQLFreeStmt(stmtHnd, SQL_CLOSE);
_tprintf(_T("Finished Update/n/n"));

rc = SQLAllocStmt(conHnd, &stmtHnd);
if (rc != SQL_SUCCESS)
{
  _tprintf(_T("Failed to allocate STMT/n"));
  goto exit2;
}
 
/* Clear Result Data */
memset(resultdata, 0, sizeof(resultdata));
chunksize = clobdatalen / 15; /* 15 times to put */
 
/* Step 1: Prepare */
rc = SQLExecDirect(stmtHnd, sqlStmt2, SQL_NTS); /* select */
checkSQLErr(envHnd, conHnd, stmtHnd, rc);
 
/* Step 2: Fetch */
rc = SQLFetch(stmtHnd);
checkSQLErr(envHnd, conHnd, stmtHnd, rc);
 
for(dtsize=0, bufp = resultdata; dtsize < sizeof(resultdata)/sizeof(TCHAR) && rc != SQL_NO_DATA; dtsize += chunksize-1, bufp += chunksize-1)
{
  if (dtsize+chunksize<sizeof(resultdata)/sizeof(TCHAR))
    len = chunksize;
  else
    len = sizeof(resultdata)/sizeof(TCHAR)-dtsize;
 
  /* Step 3: GetData */
  rc = SQLGetData(stmtHnd, 1, SQL_C_TCHAR, (SQLPOINTER)bufp, len*sizeof(TCHAR), &retchklen);
}

if (!_tcscmp(resultdata, clobdata))
{
  _tprintf(_T("Succeeded!!/n/n"));
}
else
{
  _tprintf(_T("Failed!!/n/n"));
}

パフォーマンスとチューニング

トピック:

一般的なODBCプログラミングのヒント

この項では、ODBCアプリケーションのパフォーマンスを向上させるためのいくつかの一般的なプログラミングのヒントを記述しています。

  • アプリケーションがデータソースからの接続および切断を頻繁に繰り返す場合、接続のプーリングを有効にします。プールされた接続の再利用は、接続の再確立に比べて非常に効率的です。

  • 文を準備する回数を最小限にします。可能な場合は、バインド・パラメータを使用し、別のパラメータ値に対して文を再利用できるようにします。SQLExecuteごとに文を処理するのに比べ、一度文を処理して数回実行する方がはるかに効果的です。

  • アプリケーションで取得しないとわかっている列をSELECT文に含めないでください(特にLONG列)。データベース・サーバー・プロトコルの性質上、アプリケーションが列をバインドする場合、またはSQLGetDataをバインドする場合のいずれの場合も、LONG列がSELECT文に含まれている場合は、ODBCドライバはLONG列全体の内容をフェッチする必要があります。

  • データソースを更新しないトランザクションを実行中の場合は、ODBC SQLSetConnectAttr関数の SQL_ATTR_ACCESS_MODE属性をSQL_MODE_READ_ONLYに設定します。

  • ODBCのエスケープ句を使用していない場合は、ODBC SQLSetConnectAttr関数またはODBC SQLSetStmtAttr関数のSQL_ATTR_NOSCAN属性をTRUEに設定します。

  • 行数の多い表からデータを取得する場合は、ODBCのSQLFetch関数のかわりにODBCのSQLFetchScroll関数を使用します。

  • 同じSQL文が複数回使用される場合には、OCI文キャッシュを有効にします(StatementCache=T)。

  • NUMBER列をFLOATとしてバインドすると問合せの実行が高速になります(BindAsFLOAT=T)。

  • LONGまたはLONG RAWのフェッチ中に、MaxLargeData=<value>に設定するとパフォーマンスが最適化されます。

  • Ref Cursorを戻す小さなパッケージ・プロシージャに対して大量のコールが行われるアプリケーションでUseOCIDescribeAny=Tと設定すると、パフォーマンスが向上します。

データソース構成オプション

このトピックでは、次のODBCデータソース構成オプションのパフォーマンスに関連する事項を説明します。

トピック:

結果セットの有効化

このオプションによって、プロシージャ・コールから結果セット(RefCursorなど)を返すサポートが有効になります。デフォルトでは、結果セットを返すサポートが有効です。

ODBCドライバは、RefCursorパラメータが含まれるかどうかを判断するために、データベース・サーバーへ問い合せてプロシージャのパラメータ・セットおよびそれらのデータ型を判断する必要があります。この問合せによって、最初にプロシージャが準備完了になり実行されると、追加のネットワーク・ラウンド・トリップが発生します。

LOBの有効化

このオプションによって、LOBを挿入および更新するサポートが有効になります。デフォルトは有効です。

ODBC Driverでは、LOBパラメータがあるかどうかを判断するために、データベース・サーバーを問い合せて、INSERT文またはUPDATE文の各パラメータのデータ型を判別する必要があります。INSERTまたはUPDATE文が最初に処理および実行される際、この問合せが追加のネットワーク・ラウンド・トリップを発生させます。

TIMESTAMPをDATEとしてバインド

SQL_TIMESTAMPパラメータを適切なOracleデータ型でバインドします。このオプションがTRUEである場合、SQL_TIMESTAMPはOracleのDATEデータ型でバインドされます。このオプションがFALSEである場合、SQL_TIMESTAMPはOracleのTIMESTAMPデータ型でバインドされます(デフォルト)。

カーソル・クローズの有効化

ODBC関数SQLFreeStmtSQL_CLOSEオプションは、関連するカーソルを文とともにクローズし、保留中のすべての結果を廃棄します。アプリケーションは、SQLPrepareなしで文を再実行しカーソルを再開させることができます。このオプションを使用する典型的な例は、しばらくの間アイドル状態になり、後で同じSQL文を再利用するアプリケーションの場合です。この場合、アプリケーションがアイドル状態になっている間、関連するサーバー・リソースを解放することがあります。

Oracle ODBC Driverが階層化されているOracle Call Interface (OCI)は、カーソル・クローズ機能をサポートしていません。デフォルトでは、SQL_CLOSEオプションはOracle ODBC Driverには影響がありません。カーソルおよび関連のリソースは、データベース・サーバー上にオープンされた状態で存在します。

このオプションを有効にすると、データベース・サーバー上の関連するカーソルがクローズします。ただし、その結果、SQL文の解析コンテキストが失われます。ODBCアプリケーションは、SQLPrepareコールなしで再び文を実行することができます。ただし、実際にはODBCドライバは文を解析してからすべて実行することになります。このオプションを有効にした場合、一度文を解析し、それを繰り返して実行するアプリケーションのパフォーマンスには重大な影響があります。

サーバーの関連リソースを解放することが確実に必要である場合のみ、このオプションを有効にします。

スレッド・セーフティの有効化

アプリケーションがシングル・スレッドの場合、このオプションを無効にできます。デフォルトでは、ODBCドライバは、すべての内部構造(環境、接続、文)へのアクセスがスレッド・セーフティであることを保証しています。シングル・スレッドのアプリケーションは、このオプションを無効にすることにより、スレッド・セーフティのオーバーヘッドの一部を回避できます。このオプションを無効にすることにより、通常は多少のパフォーマンスの改善がみられます。

フェッチ・バッファ・サイズ

「Oracle ODBCドライバ構成」ダイアログ・ボックス「Oracle」オプション・タブの「フェッチ・バッファ・サイズ」をバイト単位で設定します。この値は、ODBC DriverがOracle Databaseからクライントのキャッシュに1回にプリフェッチするデータの行数を決定し、アプリケーション・プログラムが1回の問合せで要求する行数とは関係ありません。これによって、パフォーマンスが向上します。

通常一度に20行未満をフェッチするアプリケーションでは、低速なネットワーク接続上で動作する場合や非常に負荷の高いサーバーにアクセスする場合には特に、レスポンス時間が向上します。これを大きく設定しすぎると、レスポンス時間が悪化したり、メモリーを大量に消費することがあります。デフォルトは64,000バイトです。アプリケーションに最適な値を選択します。

注意:

LONGおよびLOBデータ型がある場合、ODBCドライバのプリフェッチ行数は、フェッチ・バッファ・サイズに依存しません。LONGおよびLOBデータ型では、パフォーマンスの改善が見込めず、過度のメモリー消費を引き起こす可能性があります。LONGおよびLOBデータ型が存在する場合、ODBC Driverはフェッチ・バッファ・サイズを無視し、設定された行数をプリフェッチします。

DATEデータ型およびTIMESTAMPデータ型

索引を含むDATE列をWHERE句で使用すると、データベースのパフォーマンスに影響する場合があります。例:

SELECT * FROM EMP WHERE HIREDATE = ?

この例ではHIREDATE列の索引を使用して、瞬時に問合せを実行できます。ただし、HIREDATEは実際にはDATE値であり、ODBCドライバによりTIMESTAMPのパラメータ値が提供されるため、Oracleサーバーの問合せオプティマイザには変換機能を適用する必要があります。誤った結果(パラメータ値に0以外の小数秒がある場合に発生する可能性があります)を防ぐために、オプティマイザは、HIREDATE列に変換を適用するため、次のような文になります。

SELECT * FROM EMP WHERE TO_TIMESTAMP(HIREDATE) = ?

残念ながら、これによりHIREDATE列の索引の使用は無効になり、かわりにサーバーによる表のスキャンが順次実行されます。表に多くの列が含まれる場合、これには時間がかかります。この状況を回避するため、ODBCドライバには「TIMESTAMPをDATEとしてバインド」接続オプションが用意されています。このオプションが有効になっている場合、SQL_TIMESTAMPパラメータはODBCドライバによりOracleのTIMESTAMPデータ型ではなくDATEデータ型でバインドされます。これにより、問合せオプティマイザでDATE列の索引が使用できるようになります。

注意:

このオプションは、DATE列をTIMESTAMP列としてバインドするMicrosoft Accessや類似のプログラムで使用することを目的としています。実際のTIMESTAMP列がある場合、またはデータが失われる可能性がある場合は、このオプションを使用しないでください。Microsoft Accessでは、主キーとして選択されたあらゆる列を使用して、このような問合せが実行されています。

関連項目:

データ型の実装