Linux上のOracle DatabaseからWindows上のSQL Serverに接続する

どうやるんだろうね?ということで試してみたメモ。

個人的にSQL Serverには詳しくなく、最低限の動作を確認しているだけなので、必ずしも適切な設定とは限らないし、他に必要な設定が存在する可能性はある。

SQL Server側の準備

事前に Windows Server 2022 上に SQL Server 2022 Developer Edition をインストールしている。

Linux上のOracleから接続するので、サーバー認証は混合モードにしてSQL Server認証が使えるようにしておく。

また、ログインにはひとまずsaを使うので有効化して、パスワードも設定しておく。

接続先のデータベースを作成。今回は「testdb」という名前のものを準備。

このデータベース上に参照先のテーブルを作成しておく。今回は「testtab」というものを準備。

テーブルには適当なデータを投入しておく。

insert into testtab values(1, 'AAAA')

どうもこのままだとTCP/IPで別ホストからの接続ができないようなので、Sql Server Configuration Manager から必要な設定を行う。

C:\Windows\System32\SQLServerManager16.msc

SQL Server ネットワークの構成 > MSSQLSERVER のプロトコル > TCP/IP を右クリックして「有効化する」

プロパティから、どのポートが使われているかを確認しておく。

SQL Serverのサービス > SQL Server(MSSQLSERVER)を右クリックして再起動すれば完了。

ODBCドライバの準備

Linux側でODBCドライバを準備する。ドライバマネージャのunixODBCが必要で、SQL ServerのドライバとしてFreeTDSも必要(こういう表現で合っているのか?)

なお、使用しているOSはOracle Linux 8。いずれもdnfでリポジトリからインストールできるが、FreeTDSに関してはepelリポジトリの導入も必要だった。

dnf -y install unixODBC
dnf -y install epel-release
dnf -y install freetds freetds-devel

/etc/odbcinst.ini に書かれているドライバの場所に、実際にFreeTDSのドライバが配置される様子。

[FreeTDS]
Description     = Free Sybase & MS SQL Driver
Driver          = /usr/lib/libtdsodbc.so
Setup           = /usr/lib/libtdsS.so
Driver64        = /usr/lib64/libtdsodbc.so ← これ
Setup64         = /usr/lib64/libtdsS.so
Port            = 1433
[oracle@localhost ~]$ ls -l /usr/lib64/libtdsodbc.so
lrwxrwxrwx 1 root root 19 12月 16  2021 /usr/lib64/libtdsodbc.so -> libtdsodbc.so.0.0.0

/etc/odbc.ini に上記ドライバを使用するようにデータソースの設定を行う。今回は「TESTDS」というデータソース名で接続先を設定。

cat <<"EOF" > /etc/odbc.ini
[ODBC Data Sources]
TESTDS = Data Source for SQLServer

[TESTDS]
Description = Test Data Source
Driver = /usr/lib64/libtdsodbc.so
Server = 192.168.10.10
Database = testdb
Port = 1433
TDS_Version = 8.0
ClientCharset = UTF-8
EOF

これだけでもう接続はできるようになっている。以下のようにテスト可能。

[root@localhost ~]# isql -v TESTDS sa test
+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  |
|                                       |
+---------------------------------------+
SQL> select * from testtab
+------------+---------------------------------------------------+
| col1       | col2                                              |
+------------+---------------------------------------------------+
| 1          | AAAA                                              |
+------------+---------------------------------------------------+
SQLRowCount returns 1
1 rows fetched

Oracle側の準備

具体的な手順などはマニュアルに記載あり。

インストレーションおよび構成ガイド
ユーザーズ・ガイド

$ORACLE_HOME/hs/admin/init<SID>.ora に 先ほど設定したデータソースなどを記載する。

cat <<"EOF" > $ORACLE_HOME/hs/admin/initTESTDB.ora
HS_FDS_CONNECT_INFO = TESTDS
#HS_FDS_TRACE_LEVEL = DEBUG
HS_FDS_SHAREABLE_NAME = /usr/lib64/libodbc.so
HS_LANGUAGE=Japanese_Japan.AL32UTF8
HS_NLS_NCHAR=UCS2
set ODBCINI = /etc/odbc.ini
EOF

私の環境だと、HS_NLS_NCHAR の設定を適切に行わないと、以下のエラーでうまく動かなかった。

行1でエラーが発生しました。:
ORA-28500:
OracleからOracle以外のシステムへの接続で次のメッセージが戻されました:
[

$ORACLE_HOME/network/admin/listener.ora に静的設定を追加する。

cat <<"EOF" >> $ORACLE_HOME/network/admin/listener.ora
SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC=
      (SID_NAME=TESTDB)
      (ORACLE_HOME=/u01/app/oracle/product/19.0.0/ee)
      (PROGRAM=dg4odbc)
    )
  )
EOF

$ORACLE_HOME/network/admin/tnsnames.ora に接続記述子を追加する。

cat <<"EOF" >> $ORACLE_HOME/network/admin/tnsnames.ora
TESTDB=
   (DESCRIPTION=
      (ADDRESS=
         (PROTOCOL=TCP)
         (HOST=localhost)
         (PORT=1521)
      )
      (CONNECT_DATA=
         (SID=TESTDB))
      (HS=OK))
EOF

最後に、Oracle DB側にデータベースリンクを作成して、SQL Serverに接続できるようにする。

drop public database link testdb;
CREATE PUBLIC DATABASE LINK testdb CONNECT TO
sa IDENTIFIED BY "test" USING 'TESTDB';

問題なければ、データベースリンク経由でSQL ServerのテーブルをSELECTしたり、INSERTしたりできるようになる。

SQL> set lin 1000
SQL> col col2 for a20
SQL> select * from testtab@testdb;

      col1 col2
---------- --------------------
         1 AAAA

SQL> insert into testtab@testdb values(2, 'あいうえお');

1行が作成されました。

SQL> commit;

コミットが完了しました。

SQL Server Management Studio からも、Oracle側でINSERTしたデータを確認できる。

コメント