unixODBC+FreeTDS+DBD::ODBCでSQL Serverに接続する

最近はなんかのインストール作業を行うことが多いです。
前回のApache2.2.2+PHP5.1.4+MySQL5.0.21+ShareToDoに続き今日はLinuxサーバーからMS SQL Serverに接続してPerl DBIで操作できるように色々試行錯誤しました。
そのメモ。

前々職でも同じようなことをしたことがあり、そのときはSQL ServerのサーバーにActive Perlを入れてそこでDBI::Proxyserver+DBD::ODBC動かして、クライアントからはDBD::Proxy使って操作しました。
あのシステムまだ動いてるのかな…

だが、今回はサーバーにPerlをインストールすることは無理そうなので、違う方法を取ることに。
それで選んだのがunixODBC+FreeTDSという方法でした。

Unix用のODBCドライバのunixODBCとDB接続ライブラリのFreeTDSを組み合わせると行けるのです。
以下、インストールメモ。

ちなみに、ここに書かれているようにODBC-ODBC Bridge Clientを使用して接続する方法もあります。

横手ネットワーク研究所さんが非常に参考になりました。
多謝。

■unixODBCのインストール

# wget http://www.unixodbc.org/unixODBC-2.2.11.tar.gz
# tar xvzf unixODBC-2.2.11.tar.gz
# cd unixODBC-2.2.11
# ./configure --enable-gui=no
# make
# make install

■libiconvのインストール

# wget http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.10.tar.gz
# wget http://www2d.biglobe.ne.jp/~msyk/software/libiconv/libiconv-1.10-cp932.patch.gz
# tar xvzf libiconv-1.8.tar.gz
# gunzip libiconv-1.10-cp932.patch.gz
# patch -p0 < libiconv-1.10-cp932.patch
# cd libiconv-1.10
# ./configure
# make
# make install
文字コードの変換を行わない場合はlibiconvは必要ないかも

■FreeTDSのインストール

# wget ftp://ftp.ibiblio.org/pub/Linux/ALPHA/freetds/stable/freetds-stable.tgz
# wget http://rebecca.ac/milano/mt/archives/freetds-0.63.patch
# tar xvzf freetds-stable.tgz
# patch -p0 < freetds-0.63.patch
patching file freetds-0.63/src/tds/encodings.h
patching file freetds-0.63/src/tds/write.c
# cd ../freetds-0.63
# export LD_LIBRARY_PATH=/usr/local/lib
# export LD_RUN_PATH=/usr/local/lib
# ./configure --with-unixodbc --with-msdblib --with-libiconv-prefix=/usr/local/lib
# make
# make install
横手ネットワーク研究所さんところのpatchが0.62対応だったので、0.63対応版をつくりました。

■odbc.iniの編集

# vi /usr/local/etc/odbc.ini
--
[ODBC Data Sources]
freetds = FreeTDS ODBC Driver

[freetds]
Driver = /usr/local/lib/libtdsodbc.so
Description = Microsoft SQL Server
Servername = mssql
Database = dbname

■freetds.confの編集
既存のファイルの最後に以下を追記します。

# vi /usr/local/etc/freetds.conf
 --
[mssql]
        host = 192.168.XXX.XXX
        port = 1433
        tds version = 7.0
        charset = sjis
        client charset = sjis
;       language = japanese
odbc.iniのServernameとfreetds.confのセクションをあわせます。
language = japaneseを有効にしておくと何故かisqlでエラーが出るのでコメントアウトしてあります。

■接続テスト

# isql -v freetds foo bar
+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  |
|                                       |
+---------------------------------------+
SQL> select count(*) from TABLE_NAME;
+------------+
|            |
+------------+
| 554779     |
+------------+
SQLRowCount returns 1
1 rows fetched
繋がった!

■DBD::ODBCのインストール

# export ODBCHOME=/usr/local
# perl -MCPAN -e shell
cpan> install DBD::ODBC

■接続テストスクリプト作成

# vi odbc.pl
--
#!/usr/bin/perl

use strict;
use DBI;
use Data::Dumper;

my $dbh = DBI->connect('dbi:ODBC:freetds', 'foo', 'bar') or die $!;
my $sth = $dbh->prepare("select top 10 * from TABLE_NAME") or die $dbh->errstr;
$sth->execute or die $dbh->errstr;
while (my $arrayref = $sth->fetchrow_arrayref) {
    print Dumper $arrayref;
}
$sth->finish;
$dbh->disconnect;

■接続テストスクリプト実行

# perl odbc.pl
$VAR1 = [
          '1',
          'なんたら',
          'かんたら',
        ];
…
無事、日本語もちゃんと表示されました。