LinuxでODBCドライバを使ってOracleに接続する
こんにちは。データアナリティクス事業本部の松村です。
LinuxでOracleにODBC接続をする機会がありました。わりと良くあるニーズだと思いますので、知っていればどうということはない作業だと思いますが、意外と必要十分な手順を記したものが見つかりませんでしたので、まとめてみました。
unixODBCのインストール
ODBC接続を行うためには、各種DB製品のODBCドライバのほか、まずはODBCドライバマネージャが必要です。これはアプリケーションとODBCドライバ間の通信を管理するミドルウェアです。unixODBCがLinuxでは一般的、かつOracle純正のODBCドライバも対応を謳っているので、これをインストールします。
パッケージマネージャ経由でインストールする
unixODBCは、大抵のディストリビューションでパッケージマネージャの標準リポジトリに含まれていますので、これを使うのが簡単です。
ただし、Oracle ODBCドライバのバージョンごとに、推奨するunixODBCのバージョンが異なります。パッケージマネージャのunixODBCのバージョンがこれ未満の場合は、自己責任で標準外のリポジトリを探すか、後述するソースコードからのインストール手順をお試しください。
Oracle Instant Client ODBCインストール・ノート | Oracle 日本
(下の方に『Linux/UNIX向けunixODBCドライバ・マネージャの推奨バージョン』という章があります)
ここでは標準リポジトリからのインストールを紹介します。
ディストリビューションによってパッケージの名前がunixODBC
だったりunixodbc
だったりしています。私がいくつか調べた限りでは、RedHat系はunixODBC
、Debian系はunixodbc
でした。
RedHat系ディストリビューションの場合
$ sudo yum install unixODBC (略) ======================================================================================== Package アーキテクチャー バージョン リポジトリー 容量 ======================================================================================== インストール中: unixODBC x86_64 2.3.1-14.el7 base 413 k 依存性関連でのインストールをします: libtool-ltdl x86_64 2.4.2-22.el7_3 base 49 k トランザクションの要約 ======================================================================================== インストール 1 パッケージ (+1 個の依存関係のパッケージ) 総ダウンロード容量: 462 k インストール容量: 1.3 M Is this ok [y/d/N]:
インストール確認のプロンプトの前にunixODBCのバージョンが表示されますので(上の実行例では2.3.1
)、問題なければy
を入力してそのままインストール、必要なバージョンより古い場合はN
を入力して中断し、後述するソースコードからのインストールを実施します。
Debian系ディストリビューションの場合
まずはaptを-s
オプション付きで実行して、インストールされるバージョンを確認します。
$ sudo apt -s install unixodbc (略) Inst libltdl7 (2.4.6-2 Ubuntu:18.04/bionic [amd64]) Inst libodbc1 (2.3.4-1.1ubuntu3 Ubuntu:18.04/bionic [amd64]) Inst odbcinst1debian2 (2.3.4-1.1ubuntu3 Ubuntu:18.04/bionic [amd64]) [] Inst odbcinst (2.3.4-1.1ubuntu3 Ubuntu:18.04/bionic [amd64]) Inst unixodbc (2.3.4-1.1ubuntu3 Ubuntu:18.04/bionic [amd64]) Conf libltdl7 (2.4.6-2 Ubuntu:18.04/bionic [amd64]) Conf libodbc1 (2.3.4-1.1ubuntu3 Ubuntu:18.04/bionic [amd64]) Conf odbcinst1debian2 (2.3.4-1.1ubuntu3 Ubuntu:18.04/bionic [amd64]) Conf odbcinst (2.3.4-1.1ubuntu3 Ubuntu:18.04/bionic [amd64]) Conf unixodbc (2.3.4-1.1ubuntu3 Ubuntu:18.04/bionic [amd64])
unixODBCのバージョンが表示されますので(上の実行例では2.3.4
)、問題なければ今度はaptを-s
オプションなしで実行してインストールします。必要なバージョンより古い場合、次のコマンドはスキップし、後述するソースコードからのインストールを実施します。
$ sudo apt install unixodbc
ソースコードからインストールする
準備
unixODBCをソースコードからインストールするためには、以下のようにいくつかのツールが必要です。未導入の場合はパッケージマネージャからインストールします。
- automake
- autoconf
- gcc
- libtool
- make
ディストリビューションによってはこれらに依存関係が設定されており、どれかをインストールしたときに他のパッケージが一緒にインストールされることがあります。
RedHat系ディストリビューションの場合
$ sudo yum install automake $ sudo yum install autoconf $ sudo yum install gcc $ sudo yum install libtool $ sudo yum install make
Debian系ディストリビューションの場合
$ sudo apt install automake $ sudo apt install autoconf $ sudo apt install gcc $ sudo apt install libtool $ sudo apt install make
ソースコードのダウンロード
unixODBCのソースコードは以下の公式サイトから入手できます。
ソースコードはanonymous FTPとHTTPの両方で配布しています。anonymous FTPはDownload
のアイコン、HTTPはVia HTTP
の後ろのリンクです。
これをcurlで取得します。通常はHTTPで良いでしょう。たまたま私がダウンロードしようとしたときはHTTPがダウンしていましたので、FTPを使いました。
anonymous FTPの場合(URLはサイトのリンクからコピーしたものを使用してください)
$ curl -u anonymous:{password} -O ftp://ftp.unixodbc.org/pub/unixODBC/unixODBC-2.3.9.tar.gz
{password}
の部分には何を入力しても良いのですが、anonymous FTPでは自身のメールアドレスにするのがお作法とされています。
HTTPの場合(URLはサイトのリンクからコピーしたものを使用してください)
$ curl -L -O http://www.unixodbc.org/unixODBC-2.3.9.tar.gz
ビルドとインストール
ダウンロードしたファイルを展開します。バージョンなどファイル名の細かい違いは読み替えてください。
$ tar zxvf unixODBC-2.3.9.tar.gz
展開したディレクトリの中に入ります。バージョンなどディレクトリ名の細かい違いは読み替えてください。
$ cd unixODBC-2.3.9
Makefile(ビルドのための設定ファイル)を自動生成します。
$ ./configure
ビルドを実行します。
$ make
ビルドしたライブラリや設定ファイルなどをインストールします。
$ sudo make install
Oracle Instant Client ODBCのインストール
Oracle Instant Client ODBCをインストールします。ダウンロード時にOracle.comプロファイルへのサインインが必要ですので、基本的にcurlで直接ダウンロードすることはできません。Webブラウザからこの先の手順でダウンロードします。
GUIをインストールしていない等の理由でLinux上でWebブラウザを使えない場合は、他のコンピュータでダウンロードしてからSFTP等で転送します。
Oracle.comプロファイルのアカウントをお持ちでない方は、まずは以下の説明を読んだ上で登録してください。
Oracle.comプロファイルについて | Oracle 日本
肝心の登録方法が載っていませんが、こちらをご覧ください。
Oracle.comプロファイル(MyProfile)の作成方法を教えてください。
Oracle Instant Client ODBCのダウンロード
Oracle.comアカウントの登録が済んだら、まずは以下のリンクからOracle Instant Clientのページにアクセスします。
Oracle Instant Client - Oracle Databaseに接続するための無償のツールとライブラリ | Oracle 日本
『今すぐダウンロード』をクリックします。
移動したページは英語表記ですが、日本語に切り替えたい場合はURLのドメインの後ろに/jp
を追加してください。
インストールするプラットフォームをクリックします。今回は『Instant Client for Linux x86-64』を選択しました。
インストールしたいバージョンのBasicまたはBasic Lightをダウンロードします。ZIP形式とRPM形式がありますが、RPMはOracle Linux 6または7用のパッケージのようです。ダウンロード時はOracle.comプロファイルへのサインインを求められますが、その手順は省略します。
BasicとBasic Liteの違いは、後者はエラーメッセージがすべて英語であることと、対応するキャラクタセットがUS7ASCII/WE8DEC/WE8ISO8859P1/WE8MSWIN1252およびUnicodeに限られるという点です。基本的にはBasicを選んでおくのが良いでしょう。
今回は、少し古いですがバージョン12.2.0.1.0
のBasicのZIPパッケージ版で説明していきます。
もうひとつ、同じページにあるODBCドライバもダウンロードします。バージョンはBasic(Lite)と同じものを選びます。
インストール先のLinux以外のコンピュータでダウンロードした場合は、ファイルをSFTP等で転送しておきます。この手順は省略します。
Instant Client Basic(Lite)のインストール
まずはInstant Client Basic(Lite)からインストールします。手順は先ほどパッケージをダウンロードしたページの下の方の『Linux x86-64用Instant Clientのインストール(64ビット)』以下に書いてありますので、これを参考に進めていきます。
途中で出てくるコマンドにおける、バージョンなどファイル/ディレクトリ名の細かい違いは適宜読み替えてください。
パッケージの展開
インストール先のディレクトリを決めて、それがまだない場合は作成します。ここでは手順書に倣って/opt/oracle
とします。
以降の作業はファイル所有者をrootにする前提でコマンドにsu
を付けていますが、その必要がなければその他のユーザで作業しても構いません。
$ sudo mkdir -p /opt/oracle
Instant Client Basic(Lite)のZIPパッケージを展開します。-d
オプションで展開先のディレクトリを指定します(省略時はカレントディレクトリです)。
$ sudo unzip instantclient-basic-linux.x64-12.2.0.1.0.zip -d /opt/oracle
展開したディレクトリ(/opt/oracle/instantclient_12_2
のようにunzip時に出力されます)に移動します。
$ cd /opt/oracle/instantclient_12_2
シンボリックリンクの作成
Instant Client Basic(Lite)のバージョンが18.3未満の場合は、シンボリックリンクを2つ作成します。
コマンドの数字の部分は、実際に存在するファイル名のものに置き換えてください。
$ sudo ln -s libclntsh.so.12.1 libclntsh.so $ sudo ln -s libocci.so.12.1 libocci.so
libaioのインストール
libaioパッケージをインストールします。ディストリビューションによっては(ちょっと調べた限りではDebian系がそうでした)libaio1という名前の場合もあるようです。
RedHat系ディストリビューションの場合
$ sudo yum install libaio
Debian系ディストリビューションの場合
$ sudo apt install libaio1
共有ライブラリのパス設定
他にOracle製のソフトウェアをインストールしていない場合、共有ライブラリのパスにInstant Client Basic(Lite)のインストールディレクトリを設定します。方法は2つあります。
システム全体で設定したい場合は、ldconfigを使用します。
$ sudo sh -c "echo /opt/oracle/instantclient_12_2 > /etc/ld.so.conf.d/oracle-instantclient.conf" $ sudo ldconfig
ユーザごとに設定したい場合は、環境変数LD_LIBRARY_PATH
に追加します。
$ export LD_LIBRARY_PATH=/opt/oracle/instantclient_12_2:$LD_LIBRARY_PATH
後者の方法を選択した場合、通常は~/.bash_profile
にも上記コマンドと同じ内容を追加しておけば、ログイン時に自動的に環境変数が設定されます。ただし、systemdやcron等で起動したプロセスからOracleに接続する場合、通常は~/.bash_profile
をロードしませんので、他の方法で環境変数LD_LIBRARY_PATH
をセットしておく必要があります。アプリケーションによっては設定ファイルで環境変数をセットできるものもあります。
設定ファイル用ディレクトリの作成
tnsnames.ora
やsqlnet.ora
などの設定ファイルを用いて接続設定を行いたい場合は、インストールディレクトリ配下のnetwork/admin
ディレクトリに置く必要があります。バージョンが12.2以下の場合はこのディレクトリがパッケージの展開時に作られないので、それを作成します。
$ sudo mkdir -p /opt/oracle/instantclient_12_2/network/admin
Instant Client ODBCのインストール
Instant Client ODBCのインストール手順は以下に説明がありますので、これを参考にして進めていきます。
Oracle Instant Client ODBCインストール・ノート | Oracle 日本
途中で出てくるコマンドにおける、バージョンなどファイル/ディレクトリ名の細かい違いは適宜読み替えてください。
パッケージの展開
Instant Client ODBCのZIPパッケージを展開します。-d
オプションでInstant Client Basic(Lite)の展開先と同じディレクトリを指定します。
$ sudo unzip instantclient-odbc-linux.x64-12.2.0.1.0-2.zip -d /opt/oracle
展開したディレクトリ(/opt/oracle/instantclient_12_2
のようにunzip時に出力されます)に移動します。
$ cd /opt/oracle/instantclient_12_2
unixODBCへのODBCドライバの登録
unixODBCにドライバを登録するときは、odbcinst.ini
にドライバのパスを設定します。このファイルを直接編集したり、unixODBCに付属のodbcinstコマンドを使ったりすることができますが、Instant Client ODBCにもそのためのスクリプトが同梱されていますので、そちらを使うことにします。
まずはunixODBCの設定ファイルの場所を調べます。
$ odbcinst -j unixODBC 2.3.9 DRIVERS............: /usr/local/etc/odbcinst.ini SYSTEM DATA SOURCES: /usr/local/etc/odbc.ini FILE DATA SOURCES..: /usr/local/etc/ODBCDataSources USER DATA SOURCES..: /home/centos/.odbc.ini SQLULEN Size.......: 8 SQLLEN Size........: 8 SQLSETPOSIROW Size.: 8
出力される内容は環境により異なります。この先の設定で必要なものだけ説明します。
DRIVERS
odbcinst.ini
の場所を表しています。今回はソースコードからインストールしましたので/usr/local/etc/odbcinst.ini
ですが、パッケージマネージャの標準リポジトリからインストールした場合は、ほとんどが/etc/odbcinst.ini
になります。SYSTEM DATA SOURCES
- システム全体で共通のデータソース設定ファイルのパスを表しています。
USER DATA SOURCES
- 現在のOSユーザ専用のデータソース設定ファイルのパスを表しています。
以上の値を使って設定を進めます。
Instant Client ODBCに付属するスクリプトのコマンド形式は以下のとおりです。
odbc_update_ini.sh <ODBCDM_Home> [<Install_Location> <Driver_Name> <DSN> <ODBCINI>]
各パラメータの意味は以下のとおりです。
ODBCDM_Home
- 必須です。unixODBCのインストールディレクトリを指定します。少し癖があって、
odbcinst.ini
のパスのうち、/etc/odbcinst.ini
よりも前の部分(ただしパスが/etc/odbcinst.ini
の場合は/
)を指定します。 Install_Location
libsqora.so.12.1
など、ODBCドライバが存在するディレクトリのパスです。省略した場合はカレントディレクトリを指定したものと見做されます。Driver_Name
- インストールするODBCドライバを識別するための名称です。省略した場合は
Oracle 12c ODBC driver
(バージョンにより異なります)などが自動設定されます。 DSN
- ODBCのDSN名です。省略した場合は
OracleODBC-12c
(バージョンにより異なります)などが自動設定されます。 ODBCINI
- データソース設定ファイルのパスです。省略した場合はコマンドを実行したユーザーの
~/.odbc.ini
(先のodbcinstコマンドの出力結果のうちのUSER DATA SOURCES
と同じです)を指定したものと見做されます。
このスクリプトは、実行するたびにodbcinst.ini
へドライバのパスを、データソース設定ファイルにDSN設定を追記します。そのため、DSN設定だけを追加したい場合には向きません。
ドライバの登録をするときに一度だけ使用し、そのときに一緒に追記されたDSN設定をコピー&ペーストして新しいDNS設定を追記していくのが良いでしょう。
それではスクリプトを実行します。Driver_Name
はデフォルトにするために空文字、ODBCINI
にはシステム全体で共通のデータソース設定ファイルを指定します。
$ sudo ./odbc_update_ini.sh /usr/local /opt/oracle/instantclient_12_2 "" ORCL /usr/local/etc/odbc.ini
実際に設定された内容を見てみましょう。まずはodbcinst.ini
から。
$ cat /usr/local/etc/odbcinst.ini [Oracle 12c ODBC driver] Description = Oracle ODBC driver for Oracle 12c Driver = /opt/oracle/instantclient_12_2/libsqora.so.12.1 Setup = FileUsage = CPTimeout = CPReuse =
次にodbc.ini
を見てみます。接続先(ServerName
)の設定が空欄ですが、後で設定します。
$ cat /usr/local/etc/odbc.ini [ORCL] Application Attributes = T Attributes = W BatchAutocommitMode = IfAllSuccessful BindAsFLOAT = F CloseCursor = F DisableDPM = F DisableMTS = T Driver = Oracle 12c ODBC driver DSN = ORCL EXECSchemaOpt = EXECSyntax = T Failover = T FailoverDelay = 10 FailoverRetryCount = 10 FetchBufferSize = 64000 ForceWCHAR = F Lobs = T Longs = T MaxLargeData = 0 MetadataIdDefault = F QueryTimeout = T ResultSets = T ServerName = SQLGetData extensions = F Translation DLL = Translation Option = 0 DisableRULEHint = T UserID = StatementCache=F CacheBufferSize=20 UseOCIDescribeAny=F SQLTranslateErrors=F MaxTokenSize=8192 AggregateSQLType=FLOAT
ネットサービス名の登録
ODBCのDSN設定で接続先を指定しますが、そこにはネットサービス名と簡易接続ネーミングメソッドによる接続記述子が指定可能です。ネットサービス名を指定する場合は、tnsnames.ora
に予め記述しておきます。
Instant Client Basic(Lite)のインストールディレクトリ配下の/network/admin
ディレクトリにtnsnames.ora
ファイルを作成し、Oracleサーバへの接続記述子を追加します。
ORCL = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = 10.0.2.191)(PORT = 1521)) (CONNECT_DATA = (SERVICE_NAME = ORCL) ) )
DSN設定の登録
DSN設定は、システム全体で共通、もしくはOSユーザ専用のデータソース設定ファイルに記載することで行います。用途に応じてどちらかを選択します。
システム全体のデータソース設定ファイルに記載
odbcinst -j
コマンドを実行してSYSTEM DATA SOURCES
で示されるファイルを調べ、それを開きます。その中のServerName
に、先ほどtnsnames.ora
に設定したネットサービス名を設定します。
[ORCL] (略) ResultSets = T ServerName = ORCL SQLGetData extensions = F (略)
OSユーザ専用のデータソース設定ファイルに記載
ユーザ専用のファイルは~/.odbc.ini
です。ここにシステム全体で共通のデータソース設定ファイルからDSN設定をひとつコピーしてきて貼り付けます。その後先頭のセクション名とDSN
(この2つは揃えてください)、ServerName
を書き換えます。
例ではServerName
に簡易接続ネーミングメソッドによる接続記述子を指定してみました。
[ORCLPDB] (略) Driver = Oracle 12c ODBC driver DSN = ORCLPDB EXECSchemaOpt = (略) ResultSets = T ServerName = 10.0.2.191:1521/ORCLPDB SQLGetData extensions = F (略)
環境変数NLS_LANGの設定
接続先Oracleのキャラクタセットを環境変数NLS_LANG
に設定します。ここまでに設定してきた接続先OracleはAL32UTF8ですので、例ではJapanese_Japan.AL32UTF8
をセットしています。
LD_LIBRARY_PATH
と同じように、アプリケーションからOracleに接続する前に、接続先に応じた値がセットされるようにしておく必要があります。
$ export NLS_LANG=Japanese_Japan.AL32UTF8
接続テスト
ODBCの接続テストは、unixODBCに付属のiusqlユーティリティで行うことができます。これはコマンドラインベースの簡易的なSQLクライアントです。コマンドの形式は以下のとおりです。
iusql DSN {user}/{password}
まずはシステム全体のデータソース設定ファイルに記載したDSN(ORCL
)をテストしてみます。
$ iusql ORCL SYSTEM/{password} +---------------------------------------+ | Connected! | | | | sql-statement | | help [tablename] | | quit | | | +---------------------------------------+ SQL>
繋がったように見えますね。SQLを実行してみましょう。
SQL> SELECT CAST(GLOBAL_NAME AS VARCHAR2(10)) AS GLOBAL_NAME FROM GLOBAL_NAME; +------------+ | GLOBAL_NAME| +------------+ | ORCL | +------------+ SQLRowCount returns -1 1 rows fetched
結果が帰ってきました。一旦quit
と入力してiusqlを終了します。
今度はOSユーザ専用のデータソース設定ファイルに記載したDSN(ORCLPDB
)をテストしてみます。こちらは簡易接続ネーミングメソッドを使っていました。
$ iusql ORCLPDB SYSTEM/{password} +---------------------------------------+ | Connected! | | | | sql-statement | | help [tablename] | | quit | | | +---------------------------------------+ SQL> SELECT CAST(GLOBAL_NAME AS VARCHAR2(10)) AS GLOBAL_NAME FROM GLOBAL_NAME; +------------+ | GLOBAL_NAME| +------------+ | ORCLPDB | +------------+ SQLRowCount returns -1 1 rows fetched
こちらもOKです。DSNを簡易接続ネーミングメソッドで設定していても問題ありませんね。
最後に
何もわからない状態から調べ始めたので、書き上げるまでだいぶ時間がかかりましたが、作業自体は特に躓くポイントもなく単純でした。最後に確認のために、もう一度クリーンな状態のOSから作業を実施してみたのですが、10分もかからずに終わりました。
今回の内容が、これから同じ作業を始めるどなたかの助けになれば幸いです。