获得Ruby-aci信息

Ruby-aci版本

require 'staci'
puts "Ruby-aci Version :        #{STACI::LIB_VERSION}"

或者

require 'staci'
puts "Ruby-aci Version :        #{STACI::VERSION}"

Ruby-aci依赖的aci库路径

require 'staci'
puts "Ruby-aci use aci :        #{STACI::Util.dll_path}"

数据库连接

普通连接

我们使用神通数据库,在连接数据库之前,请确保:

  1. 您已经创建了一个数据库 OSRDB;
  2. 您已经在 TESTDB 中创建了表 EMPLOYEE;
  3. create table employee(first_name varchar(30),last_name varchar(30), age int,sex char,income int);
  4. 设置用户 ID "SYSDBA" 和密码 "szoscar55" 来访问 OSRDB
  5. 已经在您的机器上正确地安装了 Ruby 模块 DBI。

连接数据库示例:

#!/usr/bin/ruby -w
require 'staci'
begin
        # 连接到 神通数据库
        conn = STACI.new('SYSDBA', 'szoscar55', 'localhost:2003/OSRDB')
        # 获取服务器版本字符串,并显示
       a=[]
        cursor = conn.exec('SELECT VERSION()') { |r| a<<r; puts r.join('')}

        conn.logoff if conn
end

执行结果:

Server version: 神通数据库7.0.8.211101 for Linux(x86 64bit) (200 connections) (license invalid after 146 days)

连接字符串的说明

  1. 连接任意机器的数据库方式:
conn = STACI.new('SYSDBA', 'szoscar55', 'localhost:2003/OSRDB')
  1. 连接本地数据库方式且默认实例:
conn = STACI.new('SYSDBA', 'szoscar55')

或者

conn = STACI.new('SYSDBA/szoscar55')
  1. 服务名方式:
conn = STACI.new('SYSDBA', 'szoscar55', 'stdb')

'stdb'为配置在tnsnames.aci文件中的tns名称。

连接池连接

创建连接池:

# 连接池中最新的连接数: 1

# 连接池中最大的连接数: 5

# 连接池中连接每次增长的个数: 2

cpool = STACI::ConnectionPool.new(1, 5, 2, "SYSDBA", "szoscar55", "localhost:2003/OSRDB")

从连接池中拿取连接:

conn = STACI.new("SYSDBA", "szoscar55", cpool)

安全连接

ruby-aci依赖aci驱动,aci驱动支持了ssl安全通信,且可以通过连接字符串设置,因此ruby-aci也可以在连接字符串设置ssl通信相关配置,多个参数之间用“;”间隔,比如:

conn = STACI.new('SYSDBA', 'szoscar55', 'localhost:2003/OSRDB?ssl_wallet_enable=1;ssl_wallet_path=/opt/wallet/;ssl_wallet_pwd=szoscar55$')

详细可以设置的参数,可参考 《ACI (C/C++)程序员开发手册-->ACI编程概述-->参数配置文件-->参数说明》 中的参数及参数功能描述。

语句执行

使用 连接实例的exec方法执行sql语句。返回值的类型取决于sql语句的类型:select; insert, update and delete; create, alter and drop; and PL/SQL.

当指定bindvar时,它们在执行之前被绑定为绑定变量。

执行select语句

执行select语句会返回STACI::Cursor的实例,举例如下:

conn = STACI.new('sysdba', 'szoscar55')
cursor = conn.exec('SELECT * FROM emp')
while r = cursor.fetch()
  puts r.join(',')
end
cursor.close
conn.logoff

代码块方式执行select语句

它充当迭代器并返回已处理的行数。提取的数据作为数组传递给块。在ruby中,NULL值变为nil。

conn = STACI.new('sysdba', 'szoscar55')
num_rows = conn.exec('SELECT * FROM emp') do |r|
  puts r.join(',')
end
puts num_rows.to_s + ' rows were processed.'
conn.logoff

执行update语句

exec方法返回处理行数

conn = STACI.new('sysdba', 'szoscar55')
num_rows = conn.exec('UPDATE emp SET sal = sal * 1.1')
puts num_rows.to_s + ' rows were updated.'
conn.logoff

执行insert语句

与执行update语句一样,exec方法返回处理行数。

conn = STACI.new('sysdba', 'szoscar55')
num_rows = conn.exec('insert ......')
puts num_rows.to_s + ' rows were insert.'
conn.logoff

执行delete语句

与执行update语句一样,exec方法返回处理行数。

conn = STACI.new('sysdba', 'szoscar55')
num_rows = conn.exec('delete......')
puts num_rows.to_s + ' rows were delete.'
conn.logoff

参数绑定

Ruyb-aci中,sql语句中用冒号加参数名称的格式作为参数的占位符,比如:

Select * from emp where id = :id

:id就是一个参数的占位符,占位符的规则可参考ACI开发手册中的占位符规则。

占位符中的参数可以通过两种方式:

执行时传入参数

conn实例的exec,在后面传入参数的值,执行时同时传入sql语句和参数值,示例如下:

#!/usr/bin/ruby -w
require 'staci'
conn = STACI.new('sysdba', 'szoscar55')
num_rows = conn.exec("UPDATE EMPLOYEE SET INCOME = 500 where AGE > :age",20)
conn.logoff

执行前传入参数

Cursor实例的bind_param方法可以按照参数位置和参数名称两种方式传入参数,bind_param方法需要指定绑定的参数的类型。

按参数位置传入,位置的起始位置为1:

cursor = conn.exec("drop table data_test")
cursor = conn.exec("create table data_test (a int)")
cursor = conn.parse("insert into data_test values (:a)")
cursor.bind_param(1, 11,Integer)
cursor.exec()

按参数名称传入,参数的绑定顺序随意:

cursor = conn.exec("drop table data_test")
cursor = conn.exec("create table data_test (a int)")
cursor = conn.parse("insert into data_test values (:a)")
cursor.bind_param(':a', 11,Integer)
cursor.exec()

注解

也可以直接用yum安装rpm包,需要按照ruby及ruby-devel。

执行事务

STACI类的实例对象conn中,有commit方法和rollback方法,可以进行事务的提交和回滚;ruby-aci默认事务是手动提交的,因此对数据的更改需要执行commit方法才能提交到数据量。

可以设置conn实例的autocommit属性来修改默认事务提交方式,比如:

conn.autocommit=true

大对象操作

查询获得LOB实例进行读写

往数据库中先插入EMPTY_CLOB()对象,然后查询出来,进行读写操作:

cursor = conn.exec("drop table data_test")
conn.exec('CREATE TABLE data_test ( content CLOB)')
conn.exec("INSERT INTO data_test(content) VALUES (EMPTY_CLOB())")
cursor = conn.exec("SELECT content FROM data_test")
lob = cursor.fetch[0]
open("print1.txt") do |f|
    while s = f.read(1000)
        lob.write(s)
    end
    end
lob.close
cursor = conn.exec('select * from data_test') { |r| a<<r; puts r.join('')}

用lob实例进行读写

通过创建LOB对象方式,写入数据并查询,假定/opt目录下有个1.txt文件,内容为6个a字符,操作实例代码:

file_name="/opt/1.txt"
clob = STACI::CLOB.new(conn, File.read(file_name))
conn.exec("INSERT INTO data_test(content) VALUES (:clob)",clob)
conn.commit
clob.close
cursor = conn.exec('select * from data_test')
lob = cursor.fetch[0]
lob.read(3) => "aaa"

断开数据库

如需断开数据库连接,请使用 logoff 方法。

conn.logoff

如果用户通过 logoff方法关闭了数据库连接,回滚所有未完成的事务,应用程序就能很好地显式调用 commit 或 rollback。

错误处理

引发异常并不意味着程序的终结,可以对异常进行处理,处理发生的问题并保持程序运行,这就需要rescue关键字。resouce代码段用于挽救程序,它被限定begin和end关键字的范围内,并在中间的位置放置一个rescue子句。

begin
        resoult=100/0
rescue
        puts "Divide by 0"
        exit
end