ruby 的 DBI 总体使用同 perl 差不多,由于是纯粹面向对象,使用起来更为简洁。
一、需要的模块
gem install -r dbi ruby-oci8
当然,需要先安装好 oracle client 。
二、先看一段基本代码
-
require 'dbi'
-
-
dbh = DBI.connect('dbi:OCI8:test','user','passwd') or exit;
-
p dbh.driver_name
-
-
dbh.select_all("select * from org where rownum<3") do |row|
-
# 结果分别以 hash ,array,string 展现
-
p row.to_h
-
p row.to_a
-
p row.to_s
-
-
# 提取结果记录中某一字段,类型同数据库一致,空记录返回 nill
-
p row.by_field('ORG_NAME')
-
# 根据位置提取字段内容
-
p row.by_index(3)
-
-
p row.object_id
-
p row.clone.object_id # 复制一条记录
-
p row.dup # 同 clone 一样
-
#p row.clone_with('') # 复制一条记录结构,用给定参数初始化
-
-
row.each_with_name do |val, name|
-
printf "%-30s : %s \n", name, val.to_s
-
end
-
end
-
# 只提取第一条记录 -
row = dbh.select_one("select * from org where rownum<3")
-
p row
-
- dbh.disconnect
dbi.connect
dbh.prepare
sth.execute
sth.fetch
sth.finish
dbh.disconnect
三、DBI::ROW 解析
参考:
DBI::ROW 就是代表返回结果中的一条记录。如 sth.fetch 返回的结果就是 DBI::ROW 实例,让我们看看这个类里面有些什么:
1、
将返回结果转化成 array,格式如:[value1,value2,value3...]
源代码:
-
# File lib/dbi/row.rb, line 87
-
def to_a
-
@arr.dup
- end
2、
将返回结果转化成 hash,格式如:{col1=>val1,col2=>val2,col3=>val3...}
通过 DBI::ROW.each_with_name 实现
源代码:
-
# File lib/dbi/row.rb, line 92
-
def to_h
-
hash = {}
-
each_with_name{ |v, n| hash[n] = v}
-
hash
- end
补充:DBI::ROW 也实现了 to_s 方法,将结果转化成 String。
3、
根据字段名称,获取 row 对应字段的值。
源代码:
-
# File lib/dbi/row.rb, line 117
-
def by_field(field_name)
-
begin
-
@arr[@column_map[field_name.to_s]]
-
rescue TypeError
-
nil
-
end
- end
-
sth.fetch do |row|
-
p row.by_field(org_name)
- end
根据字段位置(0..n),获取 row 对应字段的值。
源代码:
-
# File lib/dbi/row.rb, line 112
-
def by_index(index)
-
@arr[index]
- end
-
sth.fetch do |row|
-
p row.by_field(0)
- end
克隆一条记录,dup 是 clone 的别名,两者等价。
源代码:
-
# File lib/dbi/row.rb, line 92
-
def to_h
-
hash = {}
-
each_with_name{ |v, n| hash[n] = v}
-
hash
- end
5、
克隆给定记录的结构,用 new_values 进行初始化。
源代码:
- # File lib/dbi/row.rb, line 100
- def clone_with(new_values)
- obj = Marshal.load(Marshal.dump(self))
- obj.set_values(new_values)
-
- return obj
- end
6、
对返回结果进行类型变换
源代码:
-
# File lib/dbi/row.rb, line 58
-
def convert_types(arr)
-
return arr.dup unless @convert_types
-
-
if arr.size != @column_types.size
-
raise TypeError, "Type mapping is not consistent with result"
-
end
-
new_arr = []
-
arr.each_with_index do |item, i|
-
new_arr.push((@column_types[i] || DBI::Type::Varchar).parse(item))
-
end
-
-
return new_arr
- end
例子:
7、
按键值对提取结果记录
源代码:
-
# File lib/dbi/row.rb, line 80
def each_with_name
-
@arr.each_with_index do |v, i|
-
yield v, @column_names[i]
-
end
- end
-
sth.fetch.each_with_name do |v,k|
-
printf "%s --> %s\n",k,v
- end
8、
用 new_values 修改结果记录 ,此时也会对结果记录元素进行类型转换。
源代码:
-
# File lib/dbi/row.rb, line 74
-
def set_values(new_values)
-
@arr.replace(convert_types(new_values))
- end