2009年05月18日 sqlite3-ruby(1.2.4)儂(わし)的解釈によるメモ [長年日記]
_ sqlite3-ruby(1.2.4)儂(わし)的解釈によるメモ
インストール
sqlite-amalgamation-3.6.14.tar.gz
- tar xvzf sqlite-amalgamation-3.6.14.tar.gz
- cd sqlite-3.6.14
- ./configure
- make
- make install
rubygems-1.3.3.tgz
- tar xvzf rubygems-1.3.3.tgz
- cd rubygems-1.3.3
- ruby setup.rb config
- ruby setup.rb setup
- ruby setup.rb install
sqlite3-ruby-1.2.4.tar.bz2
- cd sqlite3-ruby-1.2.4
- ruby setup.rb config
- ruby setup.rb setup
- ruby setup.rb install
サンプルスクリプト
悪魔茶屋 SQLite3のページで紹介されているスクリプトをベースにさせていただいてます。
#! /usr/bin/ruby require 'rubygems' require 'sqlite3' ##require 'nkf' #====================================================================== # # Databaseへの接続 # puts "Databaseへの接続" # db = SQLite3::Database.new('test.db') # # データベース項目へ格納する際に、自動的に型変換する # db.type_translation = true # # 排他に出会った時の最大待ち時間(msec) # # transaction使用時は無視されるよう? # db.busy_timeout(5 * 1000) # # 排他に出会った時のトラップハンドラ(busy_timeoutと同時使用不可) # # transaction使用時は無視されるよう? # #db.busy_handler("test.db"){|data, retries| # print "in busy_handler data is ",data,"\n" # print "retries is ",retries,"\n" # sleep 1; # if (retries <= 3) # return true # else # return false # end #} #====================================================================== # # トランザクションの開始(busy_timeout, busy_handlerの使用不可?) # #puts "トランザクションの開始" # ##db.transaction #====================================================================== # # テーブル削除(念のため) # puts "テーブル削除(念のため)" # sql = <<SQL drop table member; SQL begin db.execute(sql) rescue => e if (e.to_s == "no such table: member") # # ありがちなエラー(テーブル存在しない)は明示的にトラップ処理 # puts "drop error, but continue." else # # 予測できないエラーはトラップして終了 # p e puts "drop ERROR = {#{e}}" exit 1 end end #====================================================================== # # テーブル作成 # puts "テーブル作成" # sql = <<SQL create table member ( id INT PRIMARY KEY, name TEXT, job TEXT ); SQL db.execute(sql) #====================================================================== # # 2重にテーブル作成し、わざとエラーを発生させてみる # puts "2重にテーブル作成し、わざとエラーを発生させてみる" # begin db.execute(sql) rescue => e if (e.to_s == "table member already exists") # # ありがちなエラー(テーブルは既に存在する)は明示的にトラップ処理 # puts "create table error, but continue." else # # 予測できないエラーはトラップして終了 # p e puts "create table ERROR = {#{e}}" exit 1 end end #====================================================================== # # インデックス作成 # puts "インデックス作成" # sql = <<SQL create index i_member_name on member(name); SQL db.execute(sql) #====================================================================== # # データセットアップ(バインド機能使用) # puts "データセットアップ(バインド機能使用)" # sql = "insert into member (id, name, job) values (:id, :name, :job)" db.execute(sql, :id => 1, :name => '伊藤 太郎', :job => 'サラリーマン') db.execute(sql, :id => 2, :name => '山田 太郎', :job => '野球選手') db.execute(sql, :id => 3, :name => '山田 花子', :job => 'タレント')
悪魔茶屋 SQLite3のページではsqlite3にデータを格納する際にはUTF-8にしないといけない旨の記述があるが、実際に生EUCを放り込んでみても特に問題なかった。ただし、他のコード(SJIS etc)だと問題が発生するのかも。
追記:やはりUTF-8でないとマルチバイト文字を検索に利用すると不正な結果を返す事があるようす。
#====================================================================== # # 2重にデータを作成し、わざとエラーを発生させてみる # puts "2重にデータを作成し、わざとエラーを発生させてみる" # begin db.execute(sql, :id => 3, :name => '山田 花子', :job => 'タレント') rescue => e if (e.to_s == "column id is not unique") # # ありがちなエラー(指定したキーは既に存在する)は明示的にトラップ処理 # puts "insert error, but continue." else # # 予測できないエラーはトラップして終了 # p e puts "insert ERROR = {#{e}}" exit 1 end end #====================================================================== # # データの検索(バインド機能使用) # puts "データの検索(バインド機能使用)" # sql = "select * from member where id >= :val" result = db.execute(sql, :val => 1) # # 結果レコードが有れば表示する # if (result.length > 0) p result[0][0].class # => Fixnum p result[0][1].class # => String p result[0][2].class # => String end result.each do |m| puts "#{m[0]}\t#{m[1]}\t#{m[2]}" end #====================================================================== # # データの更新(バインド機能使用) # puts "データの更新(バインド機能使用)" # sql = "update member set job = :job where name = :name" db.execute(sql, :job => '裁判官', :name => '山田 太郎') # # 更新結果の確認 # puts "更新結果の確認" # sql = "select * from member where name = :name" result = db.execute(sql, :name => '山田 太郎') result.each do |m| puts "#{m[0]}\t#{m[1]}\t#{m[2]}" end #====================================================================== # # データの削除(バインド機能使用) # puts "データの削除(バインド機能使用)" # sql = "delete from member where name like :name" db.execute(sql, :name => '山田%') # # 削除結果の確認(バインド機能使用) # puts "削除結果の確認(バインド機能使用)" # sql = "select * from member where id >= :id" result = db.execute(sql, :id => 1) result.each do |m| puts "#{m[0]}\t#{m[1]}\t#{m[2]}" end #====================================================================== # # トランザクション完了 # #puts "トランザクション完了" # ##db.commit #====================================================================== # # Databaseからの切断 # puts "Databaseからの切断" # db.close
その他sqlite3の運用に関して
インデックスの再作成は、
$ sqlite3 foo.db reindex
無効領域の開放は、
$ sqlite3 foo.db vacuum