24 Oracle ODBC Driverの使用方法
24.1 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.2 すべてのユーザー
24.2.1 Oracle ODBC Driver
24.2.1.1 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アーキテクチャを示します。
* Oracle ODBCリソース・データ定義言語(DLL)ファイル(sqres
xx
.dll
。xx
は言語の略称)には、言語に関連する全情報が含まれています。使用されるデフォルトのリソース・ファイルはsqresus.dll
です。
OCIクライアント/サーバー・ソフトウェアの詳細は、OCIのマニュアルを参照してください。
関連トピック
24.2.1.2 新機能と変更点
トピック:
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の新機能
-
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アプリケーションに対する変更を必要としません。既存のアプリケーションでODBCTIMESTAMP
日付型を使用し、データベース列がTIMESTAMP
の場合、現在の動作が維持されます。データベース列
TIMESTAMP WITH TIMEZONE
またはTIMESTAMP WITH LOCAL TIMEZONE
では、ODBCTIMESTAMP_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は、
VARCHAR2
、NVARCHAR2
および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.ini
のUseOCIDescribeAny
の値を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ソフトウェアの機能は次のとおりです。
-
TIMESTAMP
をDATE
としてバインド(BTD接続文字列)新規の「
TIMESTAMP
をDATE
としてバインド」接続オプションが追加されました。これにより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
に変更されました。
関連項目:
-
Timestamp
例は、「ODBCのOracle TIMESTAMP WITH TIME ZONEおよびTIMESTAMP WITH LOCAL TIME ZONE列型のサポートについて」を参照してください -
32KBの列の作成は、『Oracle Database PL/SQL言語リファレンス』および『Oracle Database SQL言語リファレンス』を参照してください。
-
SQL翻訳フレームワークの詳細は、SQL翻訳フレームワークのアーキテクチャと概要、翻訳フレームワークのインストールと構成および移行例を参照してください
-
Oracle Databaseによる暗黙的結果のサポートの詳細は、Oracle Database移行ガイドを参照してください
-
自動増分の詳細は、『Oracle Call Interfaceプログラマーズ・ガイド』を参照してください
-
SQLMoreResults()
関数の詳細は、「表24-6」および「SQLMoreResults関数」を参照してください。
24.2.1.3 サポートされていない機能
現在の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
24.2.1.4 インストールによって作成されるファイル
次の表に、Oracle ODBC Driverキットによってインストールされるファイルを示します。
表24-1 Oracle ODBC Driverキットでインストールされるファイル
説明: | Windowsインストールのファイル名 | UNIXインストールのファイル名 |
---|---|---|
Oracle ODBCデータベース・アクセスDLL |
|
libsqora.so.nn.n (nn.nはバージョン番号を表します。たとえば、libsqora.so.20.1) |
Oracle ODBC Driver設定DLL |
|
なし |
Oracle ODBCリソースDLL |
|
なし |
日本語用のOracle ODBCリソースDLL |
|
なし |
Oracle ODBC Driverメッセージ・ファイル |
|
|
日本語用のOracle ODBC Driverメッセージ・ファイル |
|
|
Oracle ODBC Driverリリース・ノート |
||
Oracle ODBC Driver Instant Clientリリース・ノート |
|
|
Oracle ODBC Driverヘルプ・ファイル |
|
|
日本語用のOracle ODBC Driverヘルプ・ファイル |
|
|
Oracle ODBC Driver Instant Clientインストール・スクリプト |
|
|
Oracle ODBC Driver Instant Clientアンインストール・スクリプト |
|
なし |
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ファイルを参照してください。
関連項目:
-
MDACキットをダウンロードする
MDAC Kit
-
unixODBCドライバをダウンロードするUnix ODBCドライバ・マネージャ
24.2.1.5 ドライバの準拠レベル
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準拠」を参照してください
24.2.2 構成タスク
24.2.2.1 Oracle Net Servicesの構成
データソースを構成する前に、ネットワーク・データベース・サービスを構成して各Transparent Network Substrate (TNS)サービス名のエントリを構成する必要があります。これを行うには、Oracle Net Configuration Assistant (NETCA)を使用します。
NETCAを使用してtnsnames.oraファイルに各TNSサービス名のエントリを作成できます。Oracle Net Servicesのインストール時に、NETCAもインストールされます。
24.2.2.2 データソースの構成
ノート:
次の構成ステップは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は、データソースを追加する際にユーザーが入力する情報を使用してデータにアクセスします。次のステップを実行します。
-
「スタート」メニューから「プログラム」→「管理ツール」→「データ ソース (ODBC)」を選択します。インストールされているドライバのリストが表示されます。
-
新規データ ソースの作成ウィンドウで「追加」をクリックし、インストール済ドライバのリストで「Oracle ODBC Driver」を選択します。
-
「終了」をクリックします。「Oracle ODBCドライバ構成」ダイアログ・ボックスが表示されます。DSNとTNSサービス名は必ず入力する必要があります。このダイアログ・ボックスでその他の必要な情報を入力することも、フィールドを空白のままにして、アプリケーションを実行するときに情報を指定することもできます。
-
データを入力したら、「OK」をクリックするか[Enter]を押します。
データソースはいつでも変更または削除できます。次の項では、データソースの追加、変更または削除方法を説明します。
Oracleデータソースを変更するには:
-
「スタート」メニューから「プログラム」→「管理ツール」→「データ ソース (ODBC)」を選択します。
-
「ODBC データ ソース アドミニストレータ」ダイアログ・ボックスで、データソースのリストからデータソースを選択し、「構成」をクリックします。「Oracle ODBCドライバ構成」ダイアログ・ボックスが表示されます。
-
「Oracle ODBCドライバ構成」ダイアログ・ボックスで、必要に応じてオプション値を変更し、「OK」をクリックします。
Oracleデータソースを削除するには:
- 「スタート」メニューから「プログラム」→「管理ツール」→「データ ソース (ODBC)」を選択します。
- 「ODBC データ ソース アドミニストレータ」ダイアログ・ボックスで、データソースのリストから削除するデータソースを選択します。
- 「削除」、「はい」の順にクリックして、削除を確定します。
24.2.2.3 「Oracle ODBCドライバ構成」ダイアログ・ボックス
ノート:
「Oracle ODBCドライバ構成」ダイアログ・ボックスを使用できるのは、Microsoft Windowsユーザーのみです。
次のスクリーンショットは「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 ODBCドライバ構成」ダイアログ・ボックスにある「アプリケーション」タブの例を示したものです。
図24-4 「Oracle ODBCドライバ構成」ダイアログ・ボックスの「アプリケーション」オプション・タブ
![図24-4の説明が続きます 図24-4の説明が続きます](img/setup_app.gif)
「図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の説明が続きます](img/setup_ora.gif)
「図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_FLOAT
、SQL_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の説明が続きます](img/setup_work.gif)
「図24-6 「Oracle ODBCドライバ構成」ダイアログ・ボックスの「Workarounds」オプション・タブ」の説明
次のリストは、前図で示した「Workarounds」タブにあるフィールドの説明です。
-
TIMESTAMPをDATEとしてバインド - このボックスを選択すると、Oracle ODBC Driverにより、
SQL_TIMESTAMP
パラメータがOracleのTIMESTAMP
型(デフォルト)ではなくOracleDATE
型で強制的にバインドされます。 -
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_ID
はSQL_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()
の使用を強制することで、パフォーマンスが向上します。
関連項目:
-
DATEおよびTIMESTAMPの詳細は、「データ型の実装」を参照してください
-
SQL_ATTR_METADATA_ID
属性の詳細は、「ODBC API関数の実装」を参照してください -
メイン構成設定オプションは、「「Oracle ODBCドライバ構成」ダイアログ・ボックス」を参照してください
SQL Server移行オプション
次のスクリーンショットは、「Oracle ODBCドライバ構成」ダイアログ・ボックスにあるSQL Server移行オプション・タブの例を示したものです。
図24-7 「Oracle ODBCドライバ構成」ダイアログ・ボックスの「SQLServer Migration」オプション・タブ
![図24-7の説明が続きます 図24-7の説明が続きます](img/setup_ssmig.gif)
「図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ドライバ構成」ダイアログ・ボックス」を参照してください
24.2.3 oraodbc.iniファイルの変更
トピック:
24.2.3.1 ロック・タイムアウトの短縮
Oracleサーバーは、トランザクション間のロック競合が解消されるまで無期限に待機します。Oracle ODBC Driverのoraodbc.ini
ファイルのLockTimeOut
エントリを設定することで、Oracleサーバーがロックの解消を待機する時間を制限できます。LockTimeOut
パラメータに入力する値は、Oracleサーバーがリクエストしたロックを取得できない場合にタイムアウトになるまでの秒数です。次の例では、Oracleサーバーは60秒後にタイムアウトになります。
[Oracle ODBC Driver Common] LockTimeOut=60
24.2.4 データソースへの接続
トピック:
24.2.4.1 Oracleデータソースへの接続
Oracle ODBC Driverでは、データソースに接続するために、使用するコンピュータにOCIクライアント・ソフトウェアがインストールされていて、対応するリスナーがOracleサーバーで実行されていることが必要です。Oracle Net Services for Windowsは、ダイナミック・リンク・ライブラリ(DLL)に基づくアプリケーションです。Oracle Net Servicesの詳細は、Oracle Net Servicesのマニュアルを参照してください。
接続処理の一部として、アプリケーションがユーザーに情報を要求することがあります。アプリケーションからOracleデータソースについての情報を要求された場合は、次の手順を実行します。
- 「TNSサービス名」ボックスで、TNSサービス名の名前を入力します。
- 「ユーザー名」ボックスに、Oracleデータベースにアクセスするために使用する名前を入力します。
- 「パスワード」ボックスに、Oracleデータベースにアクセスするために使用するパスワードを入力します。
- 「OK」をクリックします。
アプリケーションは、データソース内のデータにアクセスするにはデータソースに接続する必要があります。データソースに接続するタイミングは、アプリケーションによって異なります。たとえば、アプリケーションがユーザーの要求時にのみデータソースに接続する場合もあれば、起動時に自動的に接続する場合もあります。アプリケーションがいつデータソースに接続するかは、そのアプリケーションのマニュアルを参照してください。
-
すべてのユーザー:
-
プログラマ:
24.2.5 トラブルシューティング
24.2.5.1 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の開発ガイドおよび関連技術に関する情報などのリソースを入手できます。
24.3 上級ユーザー
24.3.1 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ファイルに作成されます。
24.3.2 SQL文
Oracle ODBC DriverはSQL-92のエントリ・レベル仕様のスーパーセットであるSQL-99のコア仕様と広く互換性があります。Oracleの文法に加えて、ODBC仕様の付録Cで概要を説明しているベンダー固有のエスケープ・シーケンスもサポートしています。ODBCの設計に従って、Oracle ODBC Driverは固有のSQL構文をOracle Databaseに渡します。
関連項目:
-
上級ユーザーは、「データ型」を参照してください
- プログラマ
24.3.3 データ型
Oracleデータベースのデータ型はOracle ODBC DriverによってODBCのSQLデータ型にマップされます。
ノート:
Microsoft ODBC 3.52 Software Development Kit and Programmers ReferenceのAppendix Dにあるすべての変換は、適切な情報型を指定したSQLGetInfo
のコールでリストされるODBC SQLデータ型についてサポートされています。
関連項目:
-
上級ユーザー:
-
プログラマ:
24.3.4 データ型の実装
トピック:
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の汎用数値データ型にマップされていました。
関連項目:
24.3.5 データ型に関する制限事項
Oracle ODBC DriverおよびOracleデータベースでは、データ型について制限があります。次の表に制限事項を示します。
表24-2 Oracle ODBC DriverおよびOracle Databaseデータ型に関する制限事項
制限されるデータ型 | 説明: |
---|---|
リテラル |
Oracle DatabaseではSQL文内のリテラルが32Kバイトに制限されます。 |
SQL_LONGVARCHARおよびSQL_WLONGVARCHAR |
|
SQL_LONGVARCHARおよびSQL_LONGVARBINARY |
Oracleデータベースでは1つの表ではLONGデータ列を1つしか使用できません。LONGデータ型とは、 |
24.3.6 エラー・メッセージ
エラーが発生すると、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サーバーのマニュアルを参照してください。
24.4 プログラマ
トピック:
24.4.1 接続文字列のフォーマット
次の表に、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 |
|
T= F= |
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 |
|
T=強制 F=強制 |
EXC |
EXEC構文 |
T=EXEC構文有効。 F=EXEC構文無効。 |
XSM |
スキーマ・フィールド |
Default=デフォルト。 Database=データベース名。 Owner=所有者名。 |
MDI |
メタデータIDのデフォルトの設定 |
T= F= |
DPM |
|
T= F= |
BTD |
|
T= F= |
NUM |
数値の設定 |
NLS=Oracle NLS数値設定を使用(小数点および3桁区切りの決定)。 MS=Microsoft地域設定を使用。 US=US設定を使用。 |
ODA |
|
T=アプリケーションが F= |
STE |
SQLでORAエラーを変換 Oracle ODBC DriverがOracleエラー・コードを変換するかどうかを指定 |
T=ORAエラーを変換。 F=ORAエラーを変換しない。デフォルトでは、 |
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;
関連項目:
-
すべてのユーザーは、「Oracleデータソースへの接続」を参照してください
-
プログラマは、「SQLDriverConnectの実装」を参照してください
24.4.2 SQLDriverConnectの実装
次の表に、SQLDriverConnect接続文字列で必要なキーワードを示します。
表24-5 SQLDriverConnect接続文字列で必要なキーワード
キーワード | 説明: |
---|---|
DSN |
データソース名。 |
DBQ |
TNSサービス名。「Oracle ODBC DriverのTNSサービス名の作成」を参照してください。詳細は、Oracle Net Servicesのマニュアルを参照してください。 |
UID |
ユーザーのログインIDまたはユーザー名。 |
PWD |
ユーザー指定のパスワード。 |
24.4.3 プログラムでのロック・タイムアウトの短縮
Oracleサーバーは、トランザクション間のロック競合が解消されるまで無期限に待機します。データソースに接続する前にODBC SQLSetConnectAttr
関数をコールすることによって、ロック解消をOracleサーバーが待機する時間の長さを制限できます。ODBC SQLSetStmtAttr
関数のSQL_ATTR_QUERY_TIMEOUT
属性に0 (ゼロ)以外の値を指定します。
ODBC SQLSetConnectAttr
関数を使用してロック・タイムアウト値を指定すると、その値によってoraodbc.ini
ファイルに指定されている値が上書きされます。
関連項目:
oraodbc.ini
ファイルに値を指定する方法の詳細は、「ロック・タイムアウトを短縮する」を参照してください
24.4.4 odbc32.lib (Windows)またはlibodbc.so (UNIX)とのリンク
Windowsプラットフォームの場合、プログラムをリンクするときは、インポート・ライブラリodbc32.lib
とリンクする必要があります。
UNIXプラットフォームの場合は、ODBCアプリケーションをlibodbc.so
にリンクする必要があります。
24.4.5 ROWIDの情報
ODBCのSQLSpecialColumns
関数は、表内の列に関する情報を返します。Oracle ODBC Driverでは、Oracle表に対応付けられているOracleのROWIDについての情報が戻されます。
24.4.7 結果セットの有効化
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); }
24.4.8 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プロシージャ・コールのオブジェクト名では、大/小文字が区別されません。
24.4.9 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; }
24.4.10 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. } } }
24.4.11 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, ×tampcol1, sizeof(timestampcol1), NULL);
/* Bind the variable to read the value from the TIMESTAMP WITH LOCAL TIME ZONE column. */
SQLBindCol(hstmt, 2, SQL_C_TIMESTAMP, ×tampcol2, 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, ×tampcol1, sizeof(timestampcol1), NULL);
/* Bind the input value for column COL_TSLTZ. */
SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_TIMESTAMP, SQL_TIMESTAMP,
0, 0, ×tampcol2, 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);
...
...
}
24.4.12 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_SDTZ
をOS_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を特定のタイムゾーンに設定する場合
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
24.4.13 サポートされている機能
24.4.13.1 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関数の実装」を参照してください
24.4.13.2 ODBC API関数の実装
次の表は、Oracle ODBC Driverが関数を実装する方法を示したものです。
表24-6 Oracle ODBC Driverで特定の関数を実装する方法
関数 | 説明: |
---|---|
|
SQLConnectには、DBQ、ユーザーIDおよびパスワードのみが必要です。 |
|
SQLDriverConnectは、DSN、DBQ、UIDおよびPWDキーワードを使用します。 |
|
暗黙的結果のODBCサポートを実装します。これは、Oracle Database 12cリリース1 (12.1.0.1)に実装されている新しいAPIです。詳細は、SQLMoreResults関数を参照してください。 |
|
|
|
次の項を参照してください。 |
すべてのカタログ関数 |
|
24.4.13.3 ODBC SQL構文の実装
比較述語で比較の2番目の式としてパラメータ・マーカーが使用され、そのパラメータの値がSQLBindParameter
を使用してSQL_NULL_DATA
に設定されている場合、比較は失敗します。これは、ODBC SQLのNULL述語構文と一致しています。
24.4.14 Unicodeのサポート
トピック:
24.4.14.1 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をフル・サポートしています。
24.4.14.2 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_WCHAR
、SQL_WVARCHAR
およびSQL_WLONGVARCHAR
がODBCインタフェースに追加され、表内で定義された列がUnicodeで表現されるようになりました。これらの値は、SQLDescribeCol
、SQLColAttribute
、SQLColumns
およびSQLProcedureColumns
へのコールから返すことも可能です。
Unicodeエンコードは、SQL列型NCHAR
、NVARCHAR2
およびNCLOB
についてサポートされています。また、SQL列型CHAR
およびVARCHAR2
についても、キャラクタ・セマンティクスが列定義で指定されている場合は、Unicodeエンコードがサポートされます。
Oracle ODBC DriverはこれらのSQL列型をサポートしており、これらをODBC SQLデータ型にマップします。
次の表に、サポートされているSQLデータ型および対応するODBC SQLデータ型を示します。
表24-7 サポートされるSQLデータ型および対応するODBC SQLデータ型
SQLデータ型 | ODBC SQLデータ型 |
---|---|
|
|
|
|
|
|
|
|
|
|
脚注1
文字セマンティクスが列定義で指定されている場合およびデータベースの文字セットがUnicodeの場合、CHAR
はSQL_WCHAR
にマップされます。
脚注2
文字セマンティクスが列定義で指定されている場合およびデータベースの文字セットがUnicodeの場合、VARCHAR2
はSQL_WVARCHAR
にマップされます。
24.4.14.3 ドライバ・マネージャのUnicode機能
ドライバ・マネージャは、ODBCドライバがUnicodeをサポートしていないことを検出すると、次を実行します。
-
ANSI ODBCドライバをコールする前にUnicode用関数コールをANSI用関数コールに変換します。文字列引数はUnicodeからローカル・コード・ページに変換されます。たとえば、
SQLPrepareW
コールはSQLPrepare
コールに変換されます。SQL文パラメータの文字列はUnicodeからローカル・コード・ページに変換されます。 -
文字データのリターン・パラメータを、ローカル・コード・ページからUnicodeに変換します。たとえば、
SQLColAttribute
を使用して列名を戻す場合です。 -
SQL_C_WCHAR
でバインドされた列に対し、データをローカル・コード・ページからUnicodeコード・ページに変換します。 -
SQL_C_WCHAR
でバインドされた入力パラメータに対し、データをUnicodeからローカル・コード・ページに変換します。
24.4.14.4 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としてデータをフェッチすることができます。
24.4.14.5 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")); }
24.4.15 パフォーマンスとチューニング
24.4.15.1 一般的なODBCプログラミングのヒント
この項では、ODBCアプリケーションのパフォーマンスを向上させるためのいくつかの一般的なプログラミングのヒントを記述しています。
-
アプリケーションがデータソースからの接続および切断を頻繁に繰り返す場合、接続のプーリングを有効にします。プールされた接続の再利用は、接続の再確立に比べて非常に効率的です。
-
文を準備する回数を最小限にします。可能な場合は、バインド・パラメータを使用し、別のパラメータ値に対して文を再利用できるようにします。
SQLExecute
ごとに文を処理するのに比べ、一度文を処理して数回実行する方がはるかに効果的です。 -
アプリケーションで取得しないとわかっている列を
SELECT
文に含めないでください(特にLONG
列)。データベース・サーバー・プロトコルの性質上、アプリケーションが列をバインドする場合、またはSQLGetData
をバインドする場合のいずれの場合も、LONG
列がSELECT
文に含まれている場合は、ODBCドライバはLONG列全体の内容をフェッチする必要があります。 -
データソースを更新しないトランザクションを実行中の場合は、ODBC
SQLSetConnectAttr
関数のSQL_ATTR_ACCESS_MODE
属性をSQL_MODE_READ_ONLY
に設定します。 -
ODBCのエスケープ句を使用していない場合は、ODBC
SQLSetConnectAttr
関数またはODBCSQLSetStmtAttr
関数の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
と設定すると、パフォーマンスが向上します。
24.4.15.2 データソース構成オプション
このトピックでは、次の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関数SQLFreeStmt
のSQL_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はフェッチ・バッファ・サイズを無視し、設定された行数をプリフェッチします。
24.4.15.3 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では、主キーとして選択されたあらゆる列を使用して、このような問合せが実行されています。
関連項目: