`
wuhuizhong
  • 浏览: 682545 次
  • 性别: Icon_minigender_1
  • 来自: 中山
社区版块
存档分类
最新评论

Ruby访问操作Oracle数据库的例子

    博客分类:
  • ROR
阅读更多

1. DDL SQL:创建新表

#createStatesTable.rb
require 'dbi'

#数据库连接字符串:包括 DBI:OCI8:ORCL 字符串以及用户名和口令
#OCI8 部分指的是 Ruby/OCI8 驱动程序,ORCL 部分指的是数据库服务。
dbh = DBI.connect('DBI:OCI8:ORCL', 'hr', 'hr')
dbh.do("CREATE TABLE states (
           id CHAR(2) PRIMARY KEY,
       name VARCHAR2(15) NOT NULL,
       capital VARCHAR2(25) NOT NULL)")
dbh.disconnect 

 

2. DML SQL

2.1. INSERT

#populateStatesTable.rb
require 'dbi'

dbh = DBI.connect('DBI:OCI8:ORCL', 'hr', 'hr')
#注意问号在 INSERT 语句中用作占位符。
sqlInsert = "INSERT INTO states (id, name, capital)
                         VALUES (?, ?, ?)"
dbh.do(sqlInsert, "AL", "Alabama", "Birmingham")
dbh.do(sqlInsert, "AZ", "Arizona", "Phoenix")
dbh.do(sqlInsert, "CO", "Colorado", "Denver")
dbh.do(sqlInsert, "FL", "Florida", "Tallahassee")
dbh.do(sqlInsert, "MA", "Maine", "Augusta")
dbh.do(sqlInsert, "PA", "Pennsylvania", "Philadelphia")
dbh.do(sqlInsert, "UT", "Utah", "Salt Lake City")
dbh.do(sqlInsert, "WA", "Washington", "Seattle")
dbh.do(sqlInsert, "WY", "Wyoming", "Cheyenne")
dbh.commit
dbh.disconnect

 

2.2.UPDATE

#updateStatesTable.rb
require 'dbi'

dbh = DBI.connect('DBI:OCI8:ORCL', 'hr', 'hr')
#用占位符
sqlCapitalsUpdate = "UPDATE states SET capital = ? WHERE id = ?"
dbh.do(sqlCapitalsUpdate, "Montgomery", "AL")
dbh.do(sqlCapitalsUpdate, "Harrisburg", "PA")
dbh.do(sqlCapitalsUpdate, "Olympia", "WA")
#不使用任何占位符
dbh.do("UPDATE states SET id = 'ME' WHERE name = 'Maine'")
dbh.commit
dbh.disconnect

 

2.3.DELETE

DELETE执行方式与其同等的 DML 语句 INSERT 和 UPDATE 的执行方式类似。

2.4.SELECT

#queryStatesTable.rb
require 'dbi'

dbh = DBI.connect('DBI:OCI8:ORCL', 'hr', 'hr')
#数据库查询的结果集。
rs = dbh.prepare('SELECT * FROM states')
rs.execute
while rsRow = rs.fetch do
   #内置的 p 函数打印出返回的行
   p rsRow
   #Alternative output: puts rsRow
   #Alternative output: pp rsRow
end
rs.finish
dbh.disconnect     

 

2.5.使用 DBI 以表格输出查询结果

 

清单 5 queryStatesTableFormatter.rb
require 'dbi'

dbh = DBI.connect('DBI:OCI8:ORCL', 'hr', 'hr')
rs = dbh.execute('SELECT * FROM states')
rows = rs.fetch_all
column_names = rs.column_names
rs.finish
DBI::Utils::TableFormatter.ascii(column_names, rows)
dbh.disconnect

 

2.6.使用 DBI 以XML 格式输出查询结果

 

# queryStatesTableXML.rb
require 'dbi'

dbh = DBI.connect('DBI:OCI8:ORCL', 'hr', 'hr')
rs = dbh.execute('SELECT * FROM states')
states_rows = rs.fetch_all
rs.finish
DBI::Utils::XMLFormatter.table(states_rows)
dbh.disconnect   

 

3. 存储过程。

3.1.访问 PL/SQL 内置存储过程 DBMS_UTILITY.DB_VERSION(接受两个 OUT 参数)

#builtInDBVersionCompat.rb
require 'dbi'

#使用位置绑定变量,将问号 (?) 放在数据库执行字符串中.
db_read_str = 'BEGIN DBMS_UTILITY.DB_VERSION(?, ?); END;'
dbh = DBI.connect('DBI:OCI8:ORCL', 'hr', 'hr')
#使用DBI::Handle(sth_db)函数方法
sth_db = dbh.prepare(db_read_str)
#使用从1开始的连续整数来引用值。
sth_db.bind_param(1, ' ' * 50)  # allow for up to 50 chars
sth_db.bind_param(2, ' ' * 50)  # allow for up to 50 chars
sth_db.execute
#Ruby符号(:bind_value)的使用
version = sth_db.func(:bind_value, 1)
puts "Oracle DB Version: " + version
compatibility = sth_db.func(:bind_value, 2)
puts "Oracle DB Compatibility: " + compatibility
dbh.disconnect     

 

3.2.运行内置的存储函数 DBMS_METADATA.GET_DDL返回创建表所需的 DDL。

#builtInGetDDL.rb
require 'dbi'

#使用名称绑定变量,放入的是 Ruby 符号(:out1、:in1 和 :in2)
db_read_str = 'BEGIN :out1 := DBMS_METADATA.GET_DDL(object_type=>:in1, '
db_read_str += 'name=>:in2); END;'
puts db_read_str
dbh = DBI.connect('DBI:OCI8:ORCL', 'hr', 'hr')
sth_db = dbh.prepare(db_read_str)
#通过名称引用绑定变量以访问其值。
sth_db.bind_param("out1", ' ' * 20000 )
sth_db.bind_param("in1", "TABLE")
sth_db.bind_param("in2", "STATES")
sth_db.execute
puts sth_db.func("bind_value", "out1")
dbh.disconnect

4.访问安裝Oracle的操作系统

4.1.访问环境变量

#displayOracleENV.rb
#使用每种方法对 ENV 散列进行迭代,每行打印一个环境变量及其值。
ENV.each {|key ,value| print key, "=", value, "\n"}

 

4.2.访问各种配置和其他文件(如 init.ora 文件)

4.2.1.查看init.ora文件中的键值设置.

 

#displayInitOra.rb
=begin
檔案从命令行和基于控制台的用户提示符获得输入。
首先在命令行使用预定义的 Ruby 变量ARGV,尝试获取文件路径和文件名。
如果不奏效,然后提示用户输入路径。
如果用户不提供路径和文件名,则使用硬编码的路径(包括文件名)。
=end

fileName = ARGV.to_s
# example of if statement
if fileName.size < 1
  print "Enter init.ora path and name: "
  #删除从用户控制台输入中检索到的基于字符串的文件名末尾的记录分隔符。
  #惊叹号表明该方法正在执行有可能对对象危险的操作。
  fileName = gets.chomp!
end

#example of unless statement
unless fileName.size > 1
  fileName = "C:\\oracle\\product\\10.1.0\\admin\\orcl\\init.ora"
end
print "File Name: " + fileName + "!"
theFile = File.new(fileName, "r")  # read the file
text = theFile.read  # copy file's contents into string
theFile.close        # string holds file contents; close file
#使用Regexp处理正则表达式,应用于字符串的scan方法,返回与所提供的正则表达式匹配的字符串中的子字符串。
regExp = Regexp.new('^.+=.+$')
puts text.scan(regExp)

 4.2.2.比较两个 init.ora 文件并报告它们之间的差异。

#diffInitOra.rb
=begin
读入作为命令行参数传入的两个 init.ora 文件的内容。
使用pp库打印出文件的名称,如果其中一个文件未打开,则显示该文件关闭。
在从文件中读取的两个字符串之间用一个减号确定两个文件之间的差异。
=end
require 'pp'

unless ARGV.size == 2
  print "Usage: ruby arrayMagic.rb firstFile secondFile"
  exit
end

firstFile = File.new(ARGV[0], "r")
secondFile = File.new(ARGV[1], "r")
regExp = Regexp.new('^.+=.+$')
text1 = firstFile.read.scan(regExp)
text2 = secondFile.read.scan(regExp)
firstFile.close
pp firstFile
puts text1-text2, "\n"
pp secondFile
puts text2-text1
secondFile.close

5.Ruby 异常处理

5.1.使用 Ruby 的异常处理机制的示例。

#rubyExceptions.rb
=begin
关键字begin引发(抛出)异常的代码块的起始位置。
关键字raise供脚本引发(抛出)自己的异常。
关键字rescue与Java的catch关键字类似。
关键字ensure与Java的finally关键字类似,用于执行功能,无论是否遇到异常。
=end

fileName = ARGV.to_s

#obtain file name if not provided on command-line
if fileName.size < 1
  print "Enter init.ora path and name: "
  fileName = gets.chomp!
end

#ensure something has been provided for file name
begin
  if fileName.size < 1
    raise ArgumentError, "No valid file name provided" + "\n"
  end
rescue ArgumentError => argErr
  print argErr
  raise  # re-raise this exception and force script termination
end

#get file contents
begin #Begin exception handling block for file I/O
  theFile = File.new(fileName, "r")
  text = theFile.read
  theFile.close
rescue IOError
  print "I/O Error: Problem accessing file " + fileName + "\n"
  exit
rescue Errno::ENOENT
  print "ENOENT: Cannot find file " + fileName + "\n"
  exit
rescue Errno::EPERM
  print "EPERM: Insufficient rights to open " + fileName + "\n"
  raise
rescue Exception  # Catch-all: More exceptions captured than with "rescue" alone
  print "Generic error rescued (captured) during file I/O attempt." + "\n"
  raise
else
  print "Good news!  There was no problem with file I/O for " + fileName + "\n"
ensure
  print "Good or bad, file handling attempt is now complete!\n"
end #End exception handling block for file I/O

#obtain text string for regular expression
print "Enter regular expression pattern: "
pattern = gets.chomp!

begin #Begin exception handling block for regular expression
  regExp = Regexp.new(pattern)
rescue RegexpError
  print "Problem with regular expression " + regExp.to_s + "\n"
  exit  # Nothing to be done with a bad regular expression
ensure
  print "Regular expression evaluated was: " + regExp.to_s + "\n"
end #End exception handling block for regular expression

puts text.scan(regExp)

 
下图显示了运行脚本三次的结果。

第一次运行该脚本时,故意提供了一个未知的文件名以调用文件处理异常处理。
第二次运行该脚本时用正确的文件名演示 else 块的执行,并允许执行转至与正则表达式处理相关的代码块。第二次执行该脚本时,提供了一个错误的表达式以演示 RegexpError 的处理。
第三次运行该脚本时演示了脚本的完整运行,不引发异常。所有这三次运行都演示了 ensure 块的执行,因为无论是否引发(抛出)异常,所有异常处理过程中始终调用该块。

 

 

5.2.Ruby DBI 异常处理

=begin
rubyDbExceptions.rb
代码将导致抛出一个异常,因为存在一个“while 0”循环(0 的值为“true”),该循环将重复执行,直至抛出异常。由于在抛出DBI::DatabaseError之前重复调用DBI.connect 而没有正确关闭打开的连接,因此的确会抛出该异常。在这种情况下,显示的错误代码为 12520(特定于 Oracle 的数据库错误代码),错误字符串为“ORA-12520:TNS:listener could not find available handler for requested type of server.”这些输出代码和字符串值是使用适当的 DBI::DatabaseError 属性(err 和 errstr)输出的。

如果用一个数据库操作(如 SELECT 语句)替换while 循环(故意强制数据库错误),rescue、else 和 ensure 块将被激活。如果仍出现任何异常(如完整性约束),将调用适当的“rescue”块。如果没有遇到指定了 rescue 块的异常,“else”块中的代码将执行并提交事务。在任何情况下,无论是否抛出异常,都将执行“ensure”代码块,并相应地断开与处理程序的连接。

编写 Ruby 脚本时,不一定需要捕获 (rescue) 异常(考虑 Java 的非强制异常)。然而,如果您知道可能出现某些异常并希望您的脚本针对这些情况进行某些处理(如立即退出或者打印出某些与异常相关的详细信息),Ruby 可以简化异常处理。如果您不想将 rescue-else-ensure 块与抛出异常的代码块相关联,该脚本将突然停止该代码块的执行,将显示常规异常信息,执行下一个代码块。
=end

require 'dbi'

begin
  counter = 0
  while 0  # "infinite" loop because 0 resolves to "true" for Ruby conditional
    dbh = DBI.connect('DBI:OCI8:ORCL', 'hr', 'hr')
    counter += 1
    puts "DB Connection #" + counter.to_s + "\n"
    #Intentionally NOT closing with dbh.close to force DatabaseError.
  end
rescue DBI::DataError => dataErr
  dbh.rollback
  puts "DB error due to problem with data"
  puts "Error Code: #{dataErr.err}"
  puts "Error Message: #{dataErr.errstr}"
  puts "DB rollback.\n"
rescue DBI::IntegrityError => integErr
  # Example: Trying to insert same value for unique column twice.
  dbh.rollback
  puts "DB error due to integrity problem."
  puts "Error Code: #{integErr.err}"
  puts "Error Message: #{integErr.errstr}"
  puts "DB rollback.\n"
rescue DBI::InternalError => internErr
  dbh.rollback
  puts "DB error database internal error."
  puts "Error Code: #{internErr.err}"
  puts "Error Message: #{internErr.errstr}"
  puts "DB rollback.\n"
rescue DBI::NotSupportedError => notSuppErr
  dbh.rollback
  puts "DB feature not supported."
  puts "Error Code: #{notSuppErr.err}"
  puts "Error Message: #{notSuppErr.errstr}"
  puts "DB rollback.\n"
rescue DBI::OperationalError => opErr
  dbh.rollback
  puts "DB error due to problems with operation of database."
  puts "Error Code: #{opErr.err}"
  puts "Error Message: #{opErr.errstr}"
  puts "DB rollback.\n"
rescue DBI::ProgrammingError => dbProgErr
  # Example: Bad column name in SQL statement.
  dbh.rollback
  puts "DB error due to programming problem.\n"
  puts "Error Code: #{dbProgErr.err}"
  puts "Error Message: #{dbProgErr.errstr}"
  puts "DB rollback.\n"
rescue DBI::DatabaseError => dbErr
  # Catch-all for all database exceptions.
  dbh.rollback
  puts "Database exception encountered."
  puts "Error Code: #{dbErr.err}"
  puts "Error Message: #{dbErr.errstr}"
  puts "DB rollback."
rescue DBI::InterfaceError => ifError
  dbh.rollback
  puts "Problem with DBI interface encountered."
rescue RuntimeError
  dbh.rollback
  puts "Unknown error (not DB or DBI) encountered."
else
  puts "DB commit.\n"
  dbh.commit
ensure
  puts "Disconnecting database handler."
  dbh.disconnect
end     
 



  • 描述: Ruby DBI 异常
  • 大小: 24.9 KB
  • 描述: Ruby 的一些主要异常
  • 大小: 26 KB
  • 描述: 使用 Ruby 的异常处理机制的示例
  • 大小: 112.7 KB
分享到:
评论
2 楼 wuhuizhong 2009-03-19  
在Tnsnames.ora里配置。

1 楼 zhumg123 2009-03-18  
ORCL 部分指的是数据库服务
是在那里配置的

相关推荐

    logstash采集数据库数据插件

    这个插件支持多种数据库类型,包括 MySQL、PostgreSQL、Oracle、SQL Server 等,使得 Logstash 能够方便地集成到现有的数据库环境中,实时获取数据库变更的数据。 描述中提到的 "logstash-input-jdbc-4.2.1.zip" 是...

    DbEntry.Net3.9参考手册.chm

     这个版本中,例子程序访问的数据库主要是 Access,而单元测试使 用的数据库是 SQLite,通过修改配置文件中数据源部分,可以使之不需 要重新编译即可工作于其它数据库上。配置部分通过 App.config 进行, 请参阅 ...

    Ruby/MaxL-开源

    通过Ruby/MaxL,用户可以利用Ruby的灵活性和强大的语法特性来操作和管理Essbase数据库,而无需直接编写MaxL脚本。 首先,让我们深入了解一下Ruby。Ruby是一种面向对象的、动态类型的编程语言,它强调代码的简洁性和...

    轻量级的 .Net ORM DbEntry.zip

     这个版本中,例子程序访问的数据库主要是 Access,而单元测试使用的数据库是 SQLite,通过修改配置文件中数据源部分,可以使之不需要重新编译即可工作于其它数据库上。配置部分通过 App.config 进行,请参阅 ...

    ruby-bdb:Guy Decoux的Sleepycat Berkeley DB和DB XML的Ruby绑定

    Oracle分发的Berkeley DB的Ruby接口 先决条件 db&gt; = 2(db 使用--with-db-dir=$prefix选项指定此扩展名应与哪个libdb链接。 笔记 当bdb&gt; = 0.5.5时,“ nil”被存储为空字符串(不使用封送时)。 使用打开数据库 ...

    DbEntry.Net4.1教程

    对于 ORM 和 Sql 调用,它都拥有清晰和易用的接口,目前支持 SqlServer、SQLite、MySql、Access、Firebird、Oracle 等数据库。对于 WEB 开发,它既支持 ASP.NET 2.0 的 DataSource 方式,也支持 Ruby On Rails 风格...

    My SQL知识大全

    接下来通过一个具体的例子来展示如何创建数据库、创建表并插入数据。 1. **创建数据库** 首先,我们需要删除已存在的`schoool`数据库(如果存在),然后创建新的`schoool`数据库。 ```sql drop database if ...

    logstash-output-jdbc.zip

    它的输出插件是连接Logstash到各种下游系统的桥梁,"logstash-output-jdbc" 就是这样一种输出插件,用于将 Logstash 处理的数据写入关系型数据库,如 MySQL、PostgreSQL 或 Oracle 等。 在Logstash的配置文件中,`...

    JAVA上百实例源码以及开源项目源代码

    Java访问权限控制源代码 1个目标文件 摘要:Java源码,文件操作,权限控制 Java访问权限控制,为Java操作文件、写入文件分配合适的权限,定义写到文件的信息、定义文件,输出到c:/hello.txt、写信息到文件、关闭输出流...

    logstash-input-jdbc-1.0.0.zip

    Logstash 的 JDBC 输入插件允许我们从关系型数据库中提取数据,如 MySQL、PostgreSQL、Oracle 等。这个插件通过执行 SQL 查询来拉取数据,并可以配置为定期执行,实现增量数据抽取,确保数据的实时性。在1.0.0版本中...

    精通qt4编程(源代码)

    \12.3.2 使用Oracle数据库 313 \12.4 小结 325 \第13章 Qt的模板库和工具类 326 \13.1 Qt容器类 326 \13.1.1 QList、QLinkedList和QVector 327 \13.1.2 QMap、QHash 332 \13.2 QString 334 \13.2.1 隐式共享 335 \...

    精通Qt4编程(第二版)源代码

    \12.3.2 使用Oracle数据库 313 \12.4 小结 325 \第13章 Qt的模板库和工具类 326 \13.1 Qt容器类 326 \13.1.1 QList、QLinkedList和QVector 327 \13.1.2 QMap、QHash 332 \13.2 QString 334 \13.2.1 隐式共享 ...

    jdk-6u41-windows-x86.exe文件.zip

    - **改进的JDBC**:加强了JDBC API,支持SQL的存储过程和流式结果集,提高了数据库访问性能。 - **Java运行时增强**:例如,通过G1垃圾收集器提供更高效的内存管理,以及改进的类加载机制。 2. **32位与64位的...

    javaSE代码实例

    3.7.4 令人困扰的例子 37 3.8 赋值运算 37 3.8.1 普通赋值运算 37 3.8.2 运算赋值运算 38 3.9 括号及运算符间的优先级关系 38 3.10 常用数学工具包——java.lang.Math类 39 3.10.1 数学常量 39 3.10.2...

    index_shotgun:重复索引检查器

    这类似于 ,但还支持MySQL以外的数据库例子$ index_shotgun postgresql --database=index_shotgun_test# =============================# user_stocks# =============================# index_user_stocks_on_user_...

    疯狂JAVA讲义

    1.2.2 Ruby简介和优势 4 1.2.3 Python的简介和优势 5 1.3 Java程序运行机制 5 1.3.1 高级语言的运行机制 6 1.3.2 Java程序的运行机制和JVM 6 1.4 开发Java的准备 7 1.4.1 安装JDK 8 学生提问:不是说JVM是...

Global site tag (gtag.js) - Google Analytics