LoginSignup
8
7

More than 5 years have passed since last update.

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

Last updated at Posted at 2014-08-07

はじめに

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の勝利!!

8
7
1

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
  3. You can use dark theme
What you can do with signing up
8
7