LoginSignup
7

More than 5 years have passed since last update.

posted at

updated at

PerlからODBCでSQL Serverのデータを取得

はじめに

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のバージョン確認
$ 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 をインストール

cpammをインストール
# cpan App::cpanminus

makeとunixodbc-devをインストール

私の環境下ではインストールされていなかった。

CPANのコンパイルにmakeが必要です。

makeとunixodbc-devをインストール
$ sudo apt-get install make unixodbc-dev

DBD::ODBCをインストール

DBD::ODBCをインストール
# cpanm DBD::ODBC

参考サイト
Installing Perl Module

DDPをインストール

配列の中身を見せてくれる便利なライブラリーです。
日本語文字列も文字化けせずに表示してくれます。

DDPインストール
# cpanm DDP

参考サイト
Perlのデータ構造をダンプするためのモジュール群

これで取得完了。
ソースを書いてみます。

PerlでSQL Serverにアクセス

早速、47万件の商品マスターを表示させます。
まずは完成コード。

PerlでSQLServerに接続 perl-mssql.pl
# !/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;

これを設定しないと以下のようなエラーが出ます。

LongTruncOKとLongReadLenを設定してない時のエラー
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の勝利!!

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
7