CentOS5.6にSybase ASE 11.0.3.3とDBD::Sybase 1.14をインストールしてみた
下記の記事を参考に、自宅VMware Player 3.1.5上のCentOS 5.6上に Sybase ASE 11.3.3をインストールしてみた。以下の記事を参考にすればちょっと古いけど無料のSybaseをインストールすることが出来る。
CentOS5.6にSybase ASE 11.0.3.3 ESD#6をインストールしてみた – roshi.tv::blog
で、Perlから使いたのでDBD::Sybase 1.14をインストールしてみようとしたが、単純にCPANからinstall DBD::Sybaseではインストール出来なかったのでメモ。
make test時に日本語設定だと以下のような感じで
t/base……….install_driver(Sybase) failed: Can’t load ‘/root/.cpan/build/DBD-Sybase-1.14/blib/arch/auto/DBD/Sybase/Sybase.so’ for module DBD::Sybase: /opt/sybase/lib/libcomn.so: 再配置後にセグメントprotをリストアできません: 許可がありません at /usr/lib/perl5/5.8.8/i386-linux-thread-multi/DynaLoader.pm line 230.
英語環境だと下のような感じでエラーになる。
#   Failed test ‘use DBD::Sybase;’     
#   in t/autocommit.t at line 18.      
#     Tried to use ‘DBD::Sybase’.      
#     Error:  Can’t load ‘blib/arch/auto/DBD/Sybase/Sybase.so’ for module DBD::Sybase: /opt/sybase/lib/libcomn.so: cannot restore segment prot after reloc: Permission denied at /usr/lib/perl5/5.8.8/i386-linux-thread-multi/DynaLoader.pm line 230.
調べてみるとSELinuxが動いているとコンパイル時に色々問題が出るらしいのでSELinuxを一時的又は永久に無効にするとコンパイル出来る。
SELinuxを無効化する | Smart -Web Magazine
簡単にメモっておくと
SELinuxの動作状況をチェックするにはgetenforceコマンドを利用する。Enforcingと表示されれば有効な状態。PermissiveまたはDisabledと表示されれば無効な状態。
[root@localhost ~]# getenforce     
Enforcing      
[root@localhost ~]#
SELinuxの有効無効を切り替えるにはsetenforceコマンドを利用する。引数に1を渡して実行すれば有効。0を渡して実行すれば無効になる。
[root@localhost ~]# setenforce 1     
[root@localhost ~]# getenforce      
Enforcing      
[root@localhost ~]# setenforce 0      
[root@localhost ~]# getenforce      
Permissive      
[root@localhost ~]#
あと、まだ以下の様なエラーでコンパイルやtestで通らない場合がある。
our sybase home directory is /opt/sybase. Check the environment variable SYBASE if it is not the one you want!     
Using locale name "ja_JP.UTF-8" defined in environment variable LANG      
Locale name "ja_JP.UTF-8" doesn’t exist in your /opt/sybase/locales/locales.dat file      
t/autocommit….NOK 2      
#   Failed test ‘use DBD::Sybase;’      
#   in t/autocommit.t at line 18.      
#     Tried to use ‘DBD::Sybase’.      
#     Error:  DBD::Sybase initialize: cs_ctx_alloc(112) failed at /usr/lib/perl5/5.8.8/i386-linux-thread-multi/DynaLoader.pm line 253.
言語設定がちゃんとあってないと動かないみたいなのでとりあえず面倒なのでCにした。
export LANG=Cでとりあえずテストもそれなりに動くようになった。
[root@localhost ~]# export LANG=C     
[root@localhost ~]# env      
(中略)      
LANG=C      
(中略)      
[root@localhost ~]#
と言ってもすべてのテスト(13/13)にパスしなかったのが
Failed 13/13 test scripts, 0.00% okay. 218/231 subtests failed, 5.63% okay.
以下の様に(3/13)に減って76.92%はパスする様になっただけなのだが
まあ、これだけ動けばなんとかなるでしょ。ということでcpanのシェルから
force install DBD::Sybase
して強制インストールした。
perlからDBI経由でSybaseを使う場合も言語の設定が一致していないと以下の様なエラーんなる。なのでとりあえず面倒なのでというかちょっと色々やってみたけどうまくいかなかったのでとりあえず、export LANG=Cで日本語は使わないようにして利用。とりあえず勉強用なのでこれで妥協。余裕があればちゃんとしたけど古いものなのでutf-8に対応してないっぽいのと、逆にlinux側がデフォではShift_JISに対応していないのでめんどくさい。とりあえず下記のサイトが参考になるかも知れない。   
SJISを使えるようにする。 – 明日=今日×(反省+前向き)+努力
[root@localhost sybase]# perl test05.pl
The context allocation routine failed when it tried to load localization files!!     
One or more following problems may caused the failure 
Your sybase home directory is /opt/sybase. Check the environment variable SYBASE if it is not the one you want!     
Using locale name "ja_JP.UTF-8" defined in environment variable LANG      
Locale name "ja_JP.UTF-8" doesn’t exist in your /opt/sybase/locales/locales.dat file      
DBD::Sybase initialize: cs_ctx_alloc(112) failed at /usr/lib/perl5/5.8.8/i386-linux-thread-multi/DynaLoader.pm line 253.      
Compilation failed in require at test05.pl line 2.      
BEGIN failed–compilation aborted at test05.pl line 2.      
[root@localhost sybase]#
sshでサーバにログインして
/opt/sybase/bin/isql -U<ユーザ名> -P<パスワード> -S<サーバ名>
と言った感じでSybaseにログイン
/opt/sybase/bin/isql -Uzipuser2 -Pxxxxxxxx -SSYBASE -Jsjis
テストでこんなテーブルを作ってみた。
CREATE TABLE test2 (     
  name char(10),      
  zip7 char(10),      
  tel  char(15),      
  flag1 tinyint,      
  flag2 tinyint,      
  date  smalldatetime,      
)      
ちなみにSybaseではgoコマンドを入力すると実際にSQLが実行される。下のような感じ
1> select * from test2     
2> go      
 name       zip7       tel             flag1 flag2 date      
 ———- ———- ————— —– —– ————————–      
 tanaka     yamato@yam 1112222333          1     1        Nov 13 2011  6:58PM      
 tanaka2    yamato2@ya 22222               2     3        Nov 13 2011  6:58PM      
 tanaka3    yamato3@ya 3333                3     4        Nov 13 2011  6:58PM      
 tanaka3    yamato4    3333                3     4        Nov 13 2011  6:59PM      
 tanaka5    tanaka5@aa 3333                3     4        Nov 13 2011  7:02PM      
 tanaka6    tanaka6    3333                3     4        Nov 13 2011  7:02PM 
(6 rows affected)     
1>
とりあえず本当に簡単なストアドを勉強がてらに作成してみる。
CREATE PROCEDURE CursorSelect8 @IN_FLAG TINYINT,@RESULT TINYINT OUTPUT,@R2 TINYINT OUTPUT     
AS      
BEGIN      
    begin      
    SELECT      
        name,      
        flag1      
    FROM      
        test2      
    WHERE flag1 = @IN_FLAG      
    end      
    begin      
    select @RESULT = 22      
    select @R2     = 33      
    end      
    return 77      
END
単純にTera Term上から貼り付けてた。(最近までずっとPuTTYばかり使ってましたがまた最近Tera Termを触り始めました。いつのまにやらずいぶん進化してた。)
goするとエラーがあれば表示される。
1> CREATE PROCEDURE CursorSelect8 @IN_FLAG TINYINT,@RESULT TINYINT OUTPUT,@R2 TINYINT OUTPUT     
2> AS      
3> BEGIN      
4>     begin      
5>     SELECT      
6>         name,      
7>         flag1      
8>     FROM      
9>         test2      
10>     WHERE flag1 = @IN_FLAG      
11>     end      
12>     begin      
13>     select @RESULT = 22      
14>     select @R2     = 33      
15>     end      
16>     return 77      
17> END      
18> go      
1>
実際にストアドを実行すると以下の様になる。
1> declare @result tinyint,@r2 tinyint     
2> exec CursorSelect8 1,@result output,@r2 output      
3> go      
 name       flag1      
 ———- —–      
 tanaka         1 
(1 row affected, return status = 77)
Return parameters:
— —     
 22  33 
1>
これをDBIを使ってPerlで取得するには下の様なサンプルを書いてみた。(突っ込みどころ満載なのでほんとにサンプルとしてみてね。)
●ソース:test05.pl
use DBI;     
use DBD::Sybase; 
print "DBD::Sybase = $DBD::Sybase::VERSION\n";
my $user = ‘zipuser2’;     
my $passwd= ‘hogehoge’; 
my $dbh = DBI->connect("dbi:Sybase:", $user, $passwd);     
#my $hst = $dbh->prepare(‘SELECT COUNT(*) FROM test1’);      
#my $hst = $dbh->prepare(‘declare @result int exec CursorSelect1 3,@result output’);      
my $hst = $dbh->prepare(q/      
declare @result tinyint,@r2 tinyint      
exec CursorSelect8 3,@result output,@r2 output      
/); 
my $ret = $hst->execute();     
print "ret = $ret\n";      
unless($ret){      
    my $errstr = $dbh->errstr;      
    $hst->finish;      
    undef $hst;      
    $dbh->disconnect;      
    die "err=".$errstr;      
} 
while(my $ref = $hst->fetchrow_arrayref){     
    print "line: type=$hst->{syb_result_type} ".$ref->[0],’ ‘,$ref->[1], ‘ ‘,$ref->[2],"\n";      
} 
my @results = $hst->syb_output_params();     
foreach my $str(@results){      
    print "result:$str\n";      
} 
$hst->finish;     
$dbh->disconnect;
●実行結果
[kumacchi@localhost sybase]$ perl test05.pl     
DBD::Sybase = 1.14      
ret = -1      
line: type=4040 tanaka3 3      
line: type=4040 tanaka3 3      
line: type=4040 tanaka5 3      
line: type=4040 tanaka6 3      
result:22      
result:33      
[kumacchi@localhost sybase]$
ちゃんとmakeできていないからなのか、古いSybaseとDBDが噛み合ってないのか、そういうものなのかわからないが、syb_output_params()メソッドを使うとストアドのreturnの値77が取得出来なかった。22と23は取得できる。(※output_paramsなのだからやっぱりそういうものなのかな?)
そういうわけで修正してみたのが下。
●ソース:test06.pl
use DBI;     
use DBD::Sybase; 
print "DBD::Sybase = $DBD::Sybase::VERSION\n";
my $user = ‘zipuser2’;     
my $passwd= ‘hogehoge’; 
my $dbh = DBI->connect("dbi:Sybase:", $user, $passwd);     
#my $hst = $dbh->prepare(‘SELECT COUNT(*) FROM test1’);      
#my $hst = $dbh->prepare(‘declare @result int exec CursorSelect1 3,@result output’);      
my $hst = $dbh->prepare(q/      
declare @result tinyint,@r2 tinyint      
exec CursorSelect8 3,@result output,@r2 output      
/); 
my $ret = $hst->execute();     
print "ret = $ret\n";      
unless($ret){      
    my $errstr = $dbh->errstr;      
    $hst->finish;      
    undef $hst;      
    $dbh->disconnect;      
    die "err=".$errstr;      
} 
{         
while(my $ref = $hst->fetchrow_arrayref){          
    print "line: type=$hst->{syb_result_type} ".$ref->[0],’ ‘,$ref->[1], ‘ ‘,$ref->[2],"\n";          
}          
redo if $hst->{syb_more_results};          
} 
#my @results = $hst->syb_output_params();       
#foreach my $str(@results){        
#   print "result:$str\n";        
#} 
$hst->finish;     
$dbh->disconnect;
肝は   
redo if $hst->{syb_more_results};     
の部分、これでちゃんとreturn 77の値も取得できた。
[kumacchi@localhost sybase]$ perl test05.pl     
DBD::Sybase = 1.14      
ret = -1      
line: type=4040 tanaka3 3      
line: type=4040 tanaka3 3      
line: type=4040 tanaka5 3      
line: type=4040 tanaka6 3      
line: type=4043 77      
line: type=4042 22 33      
[kumacchi@localhost sybase]$
■参考
DBD::Sybase – DBIモジュールのためのSybaseデータベース・ドライバ 【perldoc.jp】
■その他
#ちょっと調べた感じではSybase ASE 11.0.3.3では@@FETCH_STATUSとかROWID()などはサポートされていないみたい。最新バージョンではサポートされているっぽい(?)。
##ASE 15.7の評価版などもSybaseのサイトからダウンロード出来るみたいだけどLinuxは64ビット版だけみたいなのと、インストール方法がよくわからなかったのでダウンロードはしたけどとりあえず保留。
#サイベース情報少ないね。





















![覆面ビリオネア[Undercover Billionaire]のUnderdog BBQでクビになったクリスティン・ミュアーのその後が気になったので調べてみた undercover billionaire](https://i0.wp.com/blog.kumacchi.com/wp-content/uploads/2022/07/undercoverbillionaire.jpg?resize=120%2C120&ssl=1)



![[Android]ASUS MeMo Pad 8 AST21を購入>WW化>root化>ロリポ化 P1160176_R](https://i0.wp.com/blog.kumacchi.com/wp-content/uploads/2015/09/P1160176_R_thumb1.jpg?resize=120%2C120&ssl=1)

![[RAMディスク]Gavotte Ramdiskを導入してみた。 Windows XP – システムプロパティ](https://i0.wp.com/blog.kumacchi.com/wp-content/uploads/2014/02/img_20080517T052214275.jpg?resize=120%2C120&ssl=1)












