この項では、SQL Anywhere DBI ドライバーを使用する Ruby アプリケーションを作成する方法の概要を説明します。DBI モジュールの完全なドキュメントについては、オンラインで http://ruby-dbi.rubyforge.org/を参照してください。
Ruby アプリケーションから DBI:SQLAnywhere インターフェイスを使用するには、Ruby DBI モジュールを使用することを最初に Ruby に通知する必要があります。これを行うには、Ruby のソースファイルの先頭近くに次の行を挿入します。
require 'dbi' |
DBI モジュールは、必要に応じて SQL Anywhere データベースドライバー (DBD) インターフェイスを自動的にロードします。
通常、データベースに対して 1 つの接続を開いてから、一連の SQL 文を実行して必要なすべての操作を実行します。接続を開くには、connect 関数を使用します。この戻り値は、接続時に後続の操作を行うために使用するデータベース接続のハンドルです。
connect 関数の呼び出しは、一般的に次の形式で行います。
dbh = DBI.connect('DBI:SQLAnywhere:server-name', user-id, password, options) |
server-name 接続先のデータベースサーバー名です。"option1=value1;option2=value2;..." というフォーマットで接続文字列を指定することもできます。
user-id 有効なユーザー ID です。この文字列が空白でない場合、接続文字列に ";UID=value" が付加されます。
password ユーザー ID に対応するパスワードです。この文字列が空白でない場合、接続文字列に ";PWD=value" が付加されます。
options DatabaseName、DatabaseFile、ConnectionName などの追加接続パラメーターのハッシュです。"option1=value1;option2=value2;..." というフォーマットで接続文字列に付加されます。
connect 関数を使用してみるには、データベースサーバーとサンプルデータベースを起動してからサンプルの Ruby スクリプトを実行します。
dbeng12 "%SQLANYSAMP12%\demo.db" |
次のコードサンプルは、SQL Anywhere サンプルデータベースへの接続を開いて閉じます。次の例では文字列 "demo" がサーバー名です。
require 'dbi' DBI.connect('DBI:SQLAnywhere:demo', 'DBA', 'sql') do |dbh| if dbh.ping print "Successfully Connected\n" dbh.disconnect() end end |
サーバー名の代わりに接続文字列を指定することもできます。たとえば、上記の場合、connect 関数の最初のパラメーターを次のように置き換えることにより、スクリプトを変更できます。
require 'dbi' DBI.connect('DBI:SQLAnywhere:SERVER=demo;DBN=demo', 'DBA', 'sql') do |dbh| if dbh.ping print "Successfully Connected\n" dbh.disconnect() end end |
接続文字列にはユーザー ID とパスワードを指定できません。これらの引数を省略すると、 Ruby DBI によってデフォルトのユーザー名とパスワードが自動的に入力されるため、UID または PWD 接続パラメーターを接続文字列に含めないでください。含めた場合は、例外がスローされます。
次の例は、追加接続パラメーターをキーと値のペアのハッシュとして connect 関数に渡す方法を示しています。
require 'dbi' DBI.connect('DBI:SQLAnywhere:demo', 'DBA', 'sql', { :ConnectionName => "RubyDemo", :DatabaseFile => "demo.db", :DatabaseName => "demo" } ) do |dbh| if dbh.ping print "Successfully Connected\n" dbh.disconnect() end end |
開かれた接続へのハンドルを取得したら、データベースに格納されているデータにアクセスして修正できます。最も単純な操作は、おそらくいくつかのローを取得して出力することです。
SQL 文は最初に実行する必要があります。文から結果セットが返された場合、ステートメントハンドルを使用して、結果セットに関するメタ情報と、結果セットのローを取得できます。次の例では、メタデータからカラム名を取得し、フェッチされた各ローのカラム名と値を表示しています。
require 'dbi' def db_query( dbh, sql ) sth = dbh.execute(sql) print "# of Fields: #{sth.column_names.size}\n" sth.fetch do |row| print "\n" sth.column_info.each_with_index do |info, i| unless info["type_name"] == "LONG BINARY" print "#{info["name"]}=#{row[i]}\n" end end end sth.finish end begin dbh = DBI.connect('DBI:SQLAnywhere:demo', 'DBA', 'sql') db_query(dbh, "SELECT * FROM Products") rescue DBI::DatabaseError => e puts "An error occurred" puts "Error code: #{e.err}" puts "Error message: #{e.errstr}" puts "Error SQLSTATE: #{e.state}" ensure dbh.disconnect if dbh end |
表示される出力の最初の数行を次に示します。
# of Fields: 8 ID=300 Name=Tee Shirt Description=Tank Top Size=Small Color=White Quantity=28 UnitPrice=9.00 ID=301 Name=Tee Shirt Description=V-neck Size=Medium Color=Orange Quantity=54 UnitPrice=14.00 |
終了したら、finish を呼び出してステートメントハンドルを解放することが重要です。finish を呼び出さなかった場合、次のようなエラーが表示される場合があります。
Resource governor for 'prepared statements' exceeded |
ハンドルのリークを検出するために、SQL Anywhere データベースサーバーでは、カーソルと準備文の数はデフォルトで接続ごとに最大 50 に制限されています。これらの制限を越えると、リソースガバナーによってエラーが自動的に生成されます。このエラーが発生したら、破棄されていない文のハンドルを確認してください。文のハンドルが破棄されていない場合は、prepare_cached を慎重に使用してください。
必要な場合、max_cursor_count と max_statement_count オプションを設定してこれらの制限を変更できます。
ローを挿入するには、開かれた接続へのハンドルが必要です。ローを挿入する最も簡単な方法は、パラメーター化された INSERT 文を使用する方法です。この場合、疑問符が値のプレースホルダーとして使用されます。この文は最初に準備されてから、新しいローごとに 1 回実行されます。新しいローの値は、execute メソッドのパラメーターとして指定されます。
require 'dbi' def db_query( dbh, sql ) sth = dbh.execute(sql) print "# of Fields: #{sth.column_names.size}\n" sth.fetch do |row| print "\n" sth.column_info.each_with_index do |info, i| unless info["type_name"] == "LONG VARBINARY" print "#{info["name"]}=#{row[i]}\n" end end end sth.finish end def db_insert( dbh, rows ) sql = "INSERT INTO Customers (ID, GivenName, Surname, Street, City, State, Country, PostalCode, Phone, CompanyName) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" sth = dbh.prepare(sql); rows.each do |row| sth.execute(row[0],row[1],row[2],row[3],row[4], row[5],row[6],row[7],row[8],row[9]) end end begin dbh = DBI.connect('DBI:SQLAnywhere:demo', 'DBA', 'sql') rows = [ [801,'Alex','Alt','5 Blue Ave','New York','NY','USA', '10012','5185553434','BXM'], [802,'Zach','Zed','82 Fair St','New York','NY','USA', '10033','5185552234','Zap'] ] db_insert(dbh, rows) dbh.commit db_query(dbh, "SELECT * FROM Customers WHERE ID > 800") rescue DBI::DatabaseError => e puts "An error occurred" puts "Error code: #{e.err}" puts "Error message: #{e.errstr}" puts "Error SQLSTATE: #{e.state}" ensure dbh.disconnect if dbh end |
![]() |
DocCommentXchange で意見交換できます
|
Copyright © 2012, iAnywhere Solutions, Inc. - SQL Anywhere 12.0.1 |