今はAS400とは言わず、”System i” と呼ぶのだそうです。 職場でAS400上のDB2のデータを加工する簡単なバッチ処理プログラムを作成する必要があったので、rubyで作成してみることにしました。
この記事は、RubyでDB2にODBC接続を行う方法についての覚書です。DB2との接続について調査し、いくつか試しましたが、
- ibm_db と言うデータベースドライバがgemで配布されているが、SQL CLI (call level interface)が必要
- AS400クライアントパッケージ Client Accessで、ODBCドライバーを提供している
- 意外とruby + windows + ODBCの記事が少ない
- gemで配布されているruby-ODBCも、odbcドライバをコンパイルする必要がある(コンパイラ必要)
と言う状態。様は直接DB2に接続するドライバの入手は意外と大変で、ODBC接続が応用が利きそうだが、バイナリのODBCを入手する必要があります。 結局、採用した構成は、以下の図の通り。
ruby DBI (+ DBD::ODBC) -- Client Access ODBC Driver -- DB2/AS400 DBI : Database Interface 汎用データベースアクセス クラス。SQLをパースし、DBDに渡す。 DBD : DBIの下位層で各データベースとの接続を行う。DB毎に用意される。
今回使用したWindows PC環境は、以下の通り。
- OS: WindowsXP
- Ruby: Active Script Ruby (ruby version 1.8.7 rubygems も同梱されたパッケージ)
- IBM AS400接続クライアント Client Access インストール済み
ODBCデータソースの設定
Windowsのコントロールパネル内の”ODBCデータソース”(だったかな)で設定します。ポイントだけ記載。
- システムDSN に追加
- client access odbc driver を使用
- serverタグの"SQLデフォルトライブラリ"に、データベースオブジェクトが格納されているライブラリを指定
Ruby DBIモジュールとODBCのDBD(DataBaseDriver)をインストール
DBIは、gem から
gem install dbi gem install dbd-odbc
ODBCドライバのインストールは、以下を参考にした。 SequelでSQL ServerにODBC接続する
- バイナリのDBD::ODBCライブラリを入手。ODBC Binding for Ruby
- i386-msvcrt-ruby-odbc.zip を入手し解凍し、所定の位置に配布
入手したsoファイル(odbc.so, odbc_utf8.so)を置いたのは、私の場合 "C:¥ruby¥lib¥ruby¥1.8¥i386-mswin32" (注: 私は ActiveScriptRuby を C:¥rubyにインストールし、パスを通しているので、この位置)
接続テストのサンプルプログラム
以下のサイトにサンプルコードが記載されていたので、一部追加して、転記します。
Ruby DB2 ODBC - how to access a DB2 database on an As/400 or iSeries
require 'odbc' require 'rubygems' # baker add require 'dbi' dbh = DBI.connect('DBI:ODBC:MY_AS400', 'MY_USER', 'MY_PASS') sth = dbh.prepare('select count(*) from my_table') sth.execute # Print out each row while row=sth.fetch do p row end sth.finish dbh.disconnect
実際に irbで試してみる
実際にirbを使って、接続テストをしてみた。
C:\Documents and Settings\baker>irb irb(main):001:0> require "odbc" => true irb(main):002:0> require "rubygems" => true irb(main):003:0> require "dbi" => true irb(main):004:0> db = DBI.connect('DBI:ODBC:データソース名','ユーザ','パスワード') => #<DBI::DatabaseHandle:0x3393f0c @trace_output=nil, @driver_name="odbc", @trace_mode=nil, @convert_types=true, @handle =#<DBI::DBD::ODBC::Database:0x3393e1c @handle=#<ODBC::Database:0x3393e58>, @attr={}>> irb(main):005:0> st = db.prepare('select count(*) from テーブル名') => #<DBI::StatementHandle:0x338f9e8 @row=nil, @prepared=true, @coltypes=nil, @trace_output=nil, @fetchable=false, @raise _error=nil, @cols=nil, @trace_mode=nil, @dbh=#<DBI::DatabaseHandle:0x3393f0c @last_statement="select count(*) from G2DNF ", @trace_output=nil, @driver_name="odbc", @trace_mode=nil, @convert_types=true, @handle=#<DBI::DBD::ODBC::Database:0x33 93e1c @handle=#<ODBC::Database:0x3393e58>, @attr={}>>, @executed=false, @convert_types=true, @handle=#<DBI::DBD::ODBC::S tatement:0x338f920 @arr=[], @statement="select count(*) from xxxxxx", @params=[], @handle=#<ODBC::Statement:0x338f984>>> irb(main):008:0> st.execute => nil irb(main):009:0> st.fetch => [234402] irb(main):010:0> st.finish => nil irb(main):011:0> db.disconnect => nil
st.finish と db.disconnectは、効いてないっぽい。(儀式?)
0 件のコメント:
コメントを投稿