はじめに
PHPでLinuxクライアントからSQL Serverを見に行くことはできるのですが、
SQL Server側のデータが
- 日本語テーブル名
- 日本語データベース名
- 日本語カラム名
- 3万件以上
という環境だとまともに取得してくれませんでした。
PHP本体側のバグらしいそうで多分、
内部EncodingがUnicode化されたPHP7を待つ他ないという状況です。
PHP側のバグであればPerlやPython、Rubyだと問題ないのだろうかと試してみたくなりました。
今回はPerlの入門も兼ねてPerlの接続にチャレンジしてみることにします。
接続方法
今回は、FreeTDSとunixODBCを使って接続する方法を取ります。
図解すると下記のようになります。
DBD::ODBC(Perl) <-> unixODBC <-> FreeTDS <-> SQL Server
unixODBCやFreeTDSのインストールや設定は
下記の私の投稿をご覧ください。
LinuxからSQL ServerにODBCで接続する
unixODBCやFreeTDSの設定が終わっているものとして次に進みます。
DBD::ODBCをGetする
Perlの確認
Linuxであれば相当絞った構成にでもしない限りPerlは入っています。
一応、Perlのバージョンの確認をしましょう。
$ Perl -v
This is perl 5, version 18, subversion 2 (v5.18.2) built for x86_64-linux-gnu-th
read-multi...(省略)...
入っていますね。
CPANでCPANM
cpanm をインストール
# cpan App::cpanminus
makeとunixodbc-devをインストール
私の環境下ではインストールされていなかった。
CPANのコンパイルにmakeが必要です。
$ sudo apt-get install make unixodbc-dev
DBD::ODBCをインストール
# cpanm DBD::ODBC
参考サイト
Installing Perl Module
DDPをインストール
配列の中身を見せてくれる便利なライブラリーです。
日本語文字列も文字化けせずに表示してくれます。
# cpanm DDP
参考サイト
Perlのデータ構造をダンプするためのモジュール群
これで取得完了。
ソースを書いてみます。
PerlでSQL Serverにアクセス
早速、47万件の商品マスターを表示させます。
まずは完成コード。
# !/usr/bin/perl -l
use strict;
use utf8;
use DBI;
my $dbh=DBI->connect('dbi:ODBC:estimate','sa','password') or die $!;
my $sth=$dbh->prepare("select [商品名1] from [システム].[dbo].[商品] where 商品ID='1000125'") or die $dbh->errstr;
# 出力エラー対策
$sth->{LongTruncOk}=1;
$sth->{LongReadLen}=2000000;
$sth->execute or die $dbh->errstr;
while(my $arrayref = $sth->fetchrow_arrayref){
use DDP;
p $arrayref;
}
$sth->finish;
$dbh->disconnect;
実行結果
$ perl perl-mssql.pl
\ [
"日本語の商品名"
]
解説
下記の部分にまず注目
大量のデータを見に行くときにLongTruncOkをEnableに
LongReadLenの長さを20000ぐらいに延長しておく必要があります。
# 出力エラー対策
$sth->{LongTruncOk}=1;
$sth->{LongReadLen}=2000000;
これを設定しないと以下のようなエラーが出ます。
DBD::ODBC::st fetchrow_arrayref failed: st_fetch/SQLFetch (long truncated DBI attribute LongTruncOk not set and/or LongReadLen too small) (SQL-HY000) at perl-mssql.pl line 15.
参考サイト
Database fetchrow_array failed long truncated DBI attribute - Stack Overflow
結論
結局、Perlで47万件のデータを何の問題も無く見れてしまった。
Perlの勝利!!