Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 11.0.1 (日本語) » SQL Anywhere サーバ - プログラミング » SQL Anywhere データ・アクセス API » Ruby 用 SQL Anywhere

 

SQL Anywhere 用 Ruby-DBI ドライバ

この項では、SQL Anywhere DBI ドライバを使用する Ruby アプリケーションを作成する方法の概要を説明します。DBI モジュールの完全なドキュメントについては、オンラインで [external link] http://ruby-dbi.rubyforge.org/ を参照してください。

DBI モジュールのロード

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 スクリプトを実行します。

dbeng11 samples-dir\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:ENG=demo;DBN=demo;UID=DBA;PWD=sql') do |dbh|
    if dbh.ping
       print "Successfully Connected\n"
       dbh.disconnect()
    end
end

ユーザ ID とパスワードは接続文字列で指定されているので、connect 関数の 2 つ目と 3 つ目のパラメータは指定する必要はありません。ただし、追加接続パラメータのハッシュを渡す場合は、ユーザ ID とパスワードのパラメータに空の文字列 ('') を指定します。

次の例は、追加接続パラメータをキーと値のペアのハッシュとして 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 VARBINARY"
                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 オプションを設定してこれらの制限を変更できます。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