概要
LinuxからOracleへ接続するためのパッケージが、Raspbian(というかDebian系列)向けにリリースされていないので、Oracleが提供するOracleLinuxを使用する。
Raspberry PiデバイスへのOracle Linuxのインストール
手順
1. OSイメージのダウンロード
Oracle Linux for Arm Downloads Raspberry Pi
バージョン 8.1 と 9.5 があるが、9.5 だと色々と不足があるので、8.1が安定。
とりあえず確認した限り、aarch64(ラズパイのCPU)向けのInstantClientがまだ提供されていません。(2025/03/25時点)
2. SDカードの作成
ダウンロードしたディスクイメージを使用して、起動用のSDカードを作成します。
Raspberry PI Imager を使用するのであれば、[OS]のリストの一番下の[Use Custom]
を選択し、ダウンロードしたディスクイメージのファイルを選択して作成できます。
3. OSの初期設定
概要のURLを参考にして、OSの初期設定を行ってください。
日本語の言語パックは入っていないのでインストールする必要があります。
dnf install langpacks-ja
localectl set-locale ja_JP.utf8
localectl set-keymap jp
OSの系列について
Oracle Linux は、RaspbianのようなDebian系列ではなく、RedHat系列のデストリビューションです。(一応、RHEL完全互換らしいです。)
RedHat系列とDebian系列の主な違いとして、パッケージの管理を apt ではなく dnf(yum) で行うことが挙げられます。
4. DNFリポジトリの解放
dnf(yum) コマンドを使用する際のリポジトリですが、デフォルトでは開発用のパッケージなどが制限されているため、これを開放しておきます。
vi /etc/yum.repos.d/oracle-linux-ol8.repo
[ol8_codeready_builder] および [ol8_distro_builder] 内の enabled=0 を 1 に変更します。
5. InstantClientのインストール
Oracleデータベースに接続するための InstantClient をインストールします。
直接 dnf コマンドで直接インストールすることが出来なかったので、一旦ダウンロードしてからのインストールになります。
(dnf のリポジトリを登録すれば、直接できるのかも?)
Home > Oracle Linux 8 Repositories > Oracle Instant Client
バージョンが、19.10 / 19 / 23 とありますのでお好みで。
・basic / basiclite (基本機能。どちらか必須。liteは英語のみの軽量版)
・devel (C/C++用ヘッダファイルなど)
・odbc / jdbc (Java/Phythonなどで接続したい場合)
・sqlplus / tools (コマンドライン用ツール)
一括で実行する場合は、以下のとおり
・wget が無かったのでインストール
・作業用フォルダとして /home/InstantClient を作成
・対象:v19.23 basic/devel/sqlplusのみ
dnf install wget
mkdir /home/InstantClient
cd /home/InstantClient
wget https://yum.oracle.com/repo/OracleLinux/OL8/oracle/instantclient/aarch64/getPackage/oracle-instantclient19.23-basic-19.23.0.0.0-1.aarch64.rpm
wget https://yum.oracle.com/repo/OracleLinux/OL8/oracle/instantclient/aarch64/getPackage/oracle-instantclient19.23-devel-19.23.0.0.0-1.aarch64.rpm
wget https://yum.oracle.com/repo/OracleLinux/OL8/oracle/instantclient/aarch64/getPackage/oracle-instantclient19.23-sqlplus-19.23.0.0.0-1.aarch64.rpm
dnf install oracle-instantclient19.23-basic-19.23.0.0.0-1.aarch64.rpm
dnf install oracle-instantclient19.23-devel-19.23.0.0.0-1.aarch64.rpm
dnf install oracle-instantclient19.23-sqlplus-19.23.0.0.0-1.aarch64.rpm
6. 環境変数の設定など
いつものヤツです。
・環境変数 ORACLE_HOME の設定
全ユーザー対象なので、.bashrcなどでは無く、profileで設定します。
/etc/profile.d 配下に oracle.sh を作成し、下記の内容を設定。
ORACLE_HOME=/usr/lib/oracle/19.23/client64
export ORACLE_HOME
※ /usr/lib/oracle 配下のフォルダはバージョンによって変わります。
※ 設定後、ログインし直さないと反映されないので気をつけてください。
・接続設定ファイル(sqlnet.ora,tnsnames.ora)を作成
ORACLE_HOME 配下に network/admin とフォルダを作成し配下に sqlnet.ora,tnsnames.ora を作成します。
※ /usr/lib/oracle/19.23/client64/lib/network フォルダが存在するので、そちらへのリンクを作成してもいいです。
・C++ ライブラリのシンボリックリンクを作成
/usr/lib/oracle/19.23/client64/lib 配下にいくつかの動的ライブラリが配置されています。
C++用のクラスが定義されているライブラリ(libocci)は、本体(libocci.so.19.1)は
存在するのですが、このままだとリンカが認識してくれませんので、シンボリックリンクを作成しておく必要があります。
cd /usr/lib/oracle/19.23/client64/lib
ln -s libocci.so.19.1 libocci.so
7. プログラムの作成
・GNU C/C++ など、開発環境をインストール。
dnf install gcc gcc-c++ make
・サンプルプログラム
#-------------- basic settings ---------------
TARGET = OraTest
SRCS = $(shell ls *.cpp)
OBJS = $(SRCS:.cpp=.o)
CC = g++
CFLAGS = -Wall -O3
CFLAGS += -I/usr/include/oracle/19.23/client64
LDFLAGS = -L/usr/lib/oracle/19.23/client64/lib
LIBS = -locci -lclntsh
$(TARGET): $(OBJS)
$(CC) $(LDFLAGS) -o $(TARGET) $(OBJS) $(LIBDIR) $(LIBS)
$(OBJS): $(SRCS)
$(CC) $(CFLAGS) -c $(SRCS)
all: clean $(OBJS) $(TARGET)
.PHONY: clean
clean:
-rm -f $(OBJS) $(TARGET) *.d
#include <string>
#include <iostream>
#include <sstream>
#include <occi.h>
#include <oratypes.h>
using namespace std;
using namespace oracle::occi;
int main(int argh, char* argv[])
{
// Open Connection
string username = "scott";
string password = "tiger";
string connection_string = "myora";
Environment* ora_env = Environment::createEnvironment(Environment::DEFAULT);
Connection* ora_conn = ora_env->createConnection(username, password, connection_string);
// for SELECT
string sql_select = "SELECT ID, EXEC_TIME FROM SAMPLE_TABLE";
Statement* ora_stmt = ora_conn->createStatement(sql_select);
ResultSet* ora_rs = ora_stmt->executeQuery();
int max_id = 0;
while (ora_rs->next()) {
int id = ora_rs->getNumber(1);
string exec = ora_rs->getString(2);
cout << id << ":" << exec << endl;
if (max_id < id) max_id = id;
}
ora_stmt->closeResultSet(ora_rs);
ora_conn->terminateStatement(ora_stmt);
// for INSERT/UPDATE/DELETE
stringstream sql_insert;
sql_insert << "INSERT INTO SAMPLE_TABLE VALUES (" << max_id + 1 << ", SYSDATE)";
ora_stmt = ora_conn->createStatement(sql_insert.str());
unsigned int effect_row = ora_stmt->executeUpdate();
ora_conn->terminateStatement(ora_stmt);
// Close Connection
ora_env->terminateConnection(ora_conn);
Environment::terminateEnvironment(ora_env);
return 0;
}