Ruby DBI Read 操作

DBI 提供了一些從數(shù)據(jù)庫(kù)獲取記錄的不同方法。假設(shè) dbh 是一個(gè)數(shù)據(jù)庫(kù)句柄,sth 是一個(gè)語(yǔ)句句柄:

序號(hào)方法 & 描述
1db.select_one( stmt, *bindvars ) => aRow | nil
執(zhí)行帶有 bindvars 綁定在參數(shù)標(biāo)記前的 stmt 語(yǔ)句。返回第一行,如果結(jié)果集為空則返回 nil。
2db.select_all( stmt, *bindvars ) => [aRow, ...] | nil

db.select_all( stmt, *bindvars ){ |aRow| aBlock }

執(zhí)行帶有 bindvars 綁定在參數(shù)標(biāo)記前的 stmt 語(yǔ)句。調(diào)用不帶有塊的該方法,返回一個(gè)包含所有行的數(shù)組。如果給出了一個(gè)塊,則會(huì)為每行調(diào)用該方法。
3sth.fetch => aRow | nil
返回下一行。如果在結(jié)果中沒(méi)有下一行,則返回 nil。
4sth.fetch { |aRow| aBlock }
為結(jié)果集中剩余的行調(diào)用給定的塊。
5sth.fetch_all => [aRow, ...]
返回保存在數(shù)組中的結(jié)果集的所有剩余的行。
6sth.fetch_many( count ) => [aRow, ...]
返回保存在 [aRow, ...] 數(shù)組中的往下第 count 行。
7sth.fetch_scroll( direction, offset=1 ) => aRow | nil
返回 direction 參數(shù)和 offset 指定的行。除了 SQL_FETCH_ABSOLUTE 和 SQL_FETCH_RELATIVE,其他方法都會(huì)丟棄參數(shù) offset。direction 參數(shù)可能的值,請(qǐng)查看下面的表格。
8sth.column_names => anArray
返回列的名稱(chēng)。
9column_info => [ aColumnInfo, ... ]
返回 DBI::ColumnInfo 對(duì)象的數(shù)組。每個(gè)對(duì)象存儲(chǔ)有關(guān)某個(gè)列的信息,并包含該列的名稱(chēng)、類(lèi)型、精度等其他更多的信息。
10sth.rows => rpc
返回執(zhí)行語(yǔ)句處理的行數(shù) Count,如果不存在則返回 nil。
11sth.fetchable? => true | false
如果可能獲取行,則返回 true,否則返回 false。
12sth.cancel
釋放結(jié)果集所占有的資源。在調(diào)用該方法后,您就不能在獲取行了,除非再次調(diào)用 execute。
13sth.finish
釋放準(zhǔn)備語(yǔ)句所占有的資源。在調(diào)用該方法后,您就不能在該對(duì)象上調(diào)用其他進(jìn)一步操作的方法了。

direction 參數(shù)

下面的值可用于 fetch_scroll 方法的 direction 參數(shù):

常量描述
DBI::SQL_FETCH_FIRST獲取第一行。
DBI::SQL_FETCH_LAST獲取最后一行。
DBI::SQL_FETCH_NEXT獲取下一行。
DBI::SQL_FETCH_PRIOR獲取上一行。
DBI::SQL_FETCH_ABSOLUTE獲取在該位置偏移處的行。
DBI::SQL_FETCH_RELATIVE獲取距離當(dāng)前行該偏移量的行。

實(shí)例

下面的實(shí)例演示了如何獲取一個(gè)語(yǔ)句的元數(shù)據(jù)。假設(shè)我們有 EMPLOYEE 表。

#!/usr/bin/ruby -w

require "dbi"

begin
     # 連接到 MySQL 服務(wù)器
     dbh = DBI.connect("DBI:Mysql:TESTDB:localhost", 
	                    "testuser", "test123")
     sth = dbh.prepare("SELECT * FROM EMPLOYEE 
	                    WHERE INCOME > ?")
     sth.execute(1000)
     if sth.column_names.size == 0 then
        puts "Statement has no result set"
        printf "Number of rows affected: %d\n", sth.rows
     else
        puts "Statement has a result set"
        rows = sth.fetch_all
        printf "Number of rows: %d\n", rows.size
        printf "Number of columns: %d\n", sth.column_names.size
        sth.column_info.each_with_index do |info, i|
          printf "--- Column %d (%s) ---\n", i, info["name"]
          printf "sql_type:         %s\n", info["sql_type"]
          printf "type_name:        %s\n", info["type_name"]
          printf "precision:        %s\n", info["precision"]
          printf "scale:            %s\n", info["scale"]
          printf "nullable:         %s\n", info["nullable"]
          printf "indexed:          %s\n", info["indexed"]
          printf "primary:          %s\n", info["primary"]
          printf "unique:           %s\n", info["unique"]
          printf "mysql_type:       %s\n", info["mysql_type"]
          printf "mysql_type_name:  %s\n", info["mysql_type_name"]
          printf "mysql_length:     %s\n", info["mysql_length"]
          printf "mysql_max_length: %s\n", info["mysql_max_length"]
          printf "mysql_flags:      %s\n", info["mysql_flags"]
      end
   end
   sth.finish
rescue DBI::DatabaseError => e
     puts "An error occurred"
     puts "Error code:    #{e.err}"
     puts "Error message: #{e.errstr}"
ensure
     # 斷開(kāi)與服務(wù)器的連接
     dbh.disconnect if dbh
end

這將產(chǎn)生以下結(jié)果:

Statement has a result set
Number of rows: 5
Number of columns: 5
--- Column 0 (FIRST_NAME) ---
sql_type:         12
type_name:        VARCHAR
precision:        20
scale:            0
nullable:         true
indexed:          false
primary:          false
unique:           false
mysql_type:       254
mysql_type_name:  VARCHAR
mysql_length:     20
mysql_max_length: 4
mysql_flags:      0
--- Column 1 (LAST_NAME) ---
sql_type:         12
type_name:        VARCHAR
precision:        20
scale:            0
nullable:         true
indexed:          false
primary:          false
unique:           false
mysql_type:       254
mysql_type_name:  VARCHAR
mysql_length:     20
mysql_max_length: 5
mysql_flags:      0
--- Column 2 (AGE) ---
sql_type:         4
type_name:        INTEGER
precision:        11
scale:            0
nullable:         true
indexed:          false
primary:          false
unique:           false
mysql_type:       3
mysql_type_name:  INT
mysql_length:     11
mysql_max_length: 2
mysql_flags:      32768
--- Column 3 (SEX) ---
sql_type:         12
type_name:        VARCHAR
precision:        1
scale:            0
nullable:         true
indexed:          false
primary:          false
unique:           false
mysql_type:       254
mysql_type_name:  VARCHAR
mysql_length:     1
mysql_max_length: 1
mysql_flags:      0
--- Column 4 (INCOME) ---
sql_type:         6
type_name:        FLOAT
precision:        12
scale:            31
nullable:         true
indexed:          false
primary:          false
unique:           false
mysql_type:       4
mysql_type_name:  FLOAT
mysql_length:     12
mysql_max_length: 4
mysql_flags:      32768