设为首页 收藏本站
查看: 664|回复: 0

[经验分享] RoR 調用 Oracle Function/Procedure

[复制链接]

尚未签到

发表于 2016-7-24 11:46:18 | 显示全部楼层 |阅读模式
1.簡單的例子:
  

=begin
--創建Oracle Function
create or replace function FUN_TEST(P_STR VARCHAR2) return varchar2 is
Result varchar2(100);
begin
Result := P_STR||'-OK! FUNCTION EXECUTED.';
return(Result);
end FUN_TEST;
=end
require 'oci8'
conn = OCI8.new("hr","hr","192.168.0.1/sid")
cursor = conn.parse <<-EOS
BEGIN
:return := FUN_TEST(:p_string);
END;
EOS
cursor.bind_param(':p_string',"xxx",String)
cursor.bind_param(':return',nil,String,4000)
cursor.exec
puts cursor[':return']
cursor.close
  

2.Module的例子: 

# activerecord.rb: Using ActiveRecord, the ORM module
require 'rubygems'
require 'active_record'
# Establish a connection to Oracle
ActiveRecord::Base.establish_connection(
:adapter => "oci",
:host    => '192.168.0.1/sid',
:username => 'hr',
:password => 'password' )
module SQLStatement
class NoTypeResult < StandardError
end # class
class SQLProc
attr_reader :outs
attr_accessor :name, :arguments
def initialize( args = nil )
@name = args[:name] unless args[:name].nil?
@arguments = args[:arguments] unless args[:arguments].nil?
@conn = ActiveRecord::Base.connection.raw_connection
end # def initialize
def exec( args = nil )
unless args.nil? || ( !args.is_a? Hash )
args.each { |k, v| @arguments[k.to_s.intern] = args[k] }
end # unless
func_args = ''
@arguments.each { |k, v| func_args += "#{func_args == '' ? '' : ', '}#{k.to_s} => :#{k.to_s}"}
sql = "BEGIN #{@name}( #{func_args} );END;"
cursor = @conn.parse( sql )
@arguments.each do |k, v|
cursor.bind_param( ":#{k.to_s}", v)
end # each
cursor.exec()
#outs
@outs = []
@arguments.each do |k, v|
@outs <<  cursor[":#{k.to_s}"]
end # each
cursor.close
end # def exec
end # class SQLProc
class SQLFunc < SQLProc
attr_reader :result
attr_accessor :result_type,:result_length
def initialize( args = nil )
@result_type = args[:result_type] unless args[:result_type].nil?
@result_length = args[:result_length] unless args[:result_length].nil?
super( args )
end # def
def exec( args = nil )
if @result_type.nil?
raise NoTypeResult, 'No type for result setting', caller
end # if
unless args.nil? || ( !args.is_a? Hash )
args.each { |k, v| @arguments[k.to_s.intern] = args[k] }
end # unless
func_args = ''
@arguments.each { |k, v| func_args += "#{func_args == '' ? '' : ', '}#{k.to_s} => :#{k.to_s}"}
sql = "BEGIN :result := #{@name}( #{func_args} );END;"
cursor = @conn.parse( sql )
@arguments.each do |k, v|
cursor.bind_param( ":#{k.to_s}", v )
end # each
#cursor.bind_param( ":result", nil, @result_type )
#cursor.bind_param(":result",Fixnum)
#cursor.bind_param( ":result", nil, String,100 )
cursor.bind_param( ":result", nil, @result_type,@result_length )
cursor.exec()
@result = cursor[':result']
cursor.close
end # def exec
end # class
end # module SQLStatment
#Example of use:
=begin
CREATE OR REPLACE PROCEDURE pro_test(p1 in varchar2, p2 out varchar2) is
BEGIN
select p1 || '-OK! PROCEDURE EXECUTED.' into p2 from dual;
end pro_test;
=end
puts 'Example of procedure:'
procedure= SQLStatement::SQLProc.new(
:name => 'pro_test',
:arguments => {
:p1 =>'ruby call',
:p2 =>' '*100}
)
procedure.exec
puts procedure.outs[1]
=begin
create or replace function FUN_TEST(P_STR VARCHAR2) return varchar2 is
Result varchar2(100);
begin
Result := P_STR||'-OK! FUNCTION EXECUTED.';
return(Result);
end FUN_TEST;
=end
puts 'Example of function:'
function = SQLStatement::SQLFunc.new(
:name => 'fun_test',
:result_type => String,
:result_length => 100,
:arguments => {
:p_str =>'ruby call'}
)
function.exec
#raise function.result.inspect
puts function.result

  

3.應用的例子:

第一步:創建應用(ROR)

rails app
第二步:配置資料連接(ROR)

#database.yml
development:
adapter: oci
host: (DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.1)(PORT = 1521)))(CONNECT_DATA = (SERVICE_NAME = MYDB.MYDOMAIN.COM)))
username: scott
password: tiger

第三步:創建存儲過程(Oracle)

--Stored_proc.pks:
CREATE OR REPLACE PACKAGE stored_proc AS
type row_type is record (
name emp.ename%type,
job emp.job%type
);
TYPE table_type IS TABLE OF row_type;
procedure stored_proc(p_empno IN emp.empno%type, p_arr OUT table_type);
END stored_proc;
/
--Stored_proc.pkb:
CREATE OR REPLACE package body stored_proc as
procedure stored_proc(
p_empno emp.empno%type
, p_arr OUT table_type
) is
begin
select
ename
, job
BULK COLLECT
into p_arr
from
emp
where emp.empno=p_empno;
end;
end stored_proc;
/

 第四步:增加管道函數(Oracle)

create or replace function test_pipe(p_empno emp.empno%type default null) return stored_proc.table_type
pipelined
is
v_arr stored_proc.table_type;
begin
stored_proc.stored_proc(nvl(p_empno, 7369), v_arr);
for i in v_arr.first..v_arr.last loop
pipe row(v_arr(i));
end loop;
return;
end test_pipe;
/
 第五步:創建虛擬視圖(Oracle)

create or replace view samples(name, job)
as
select
name
, job
from
table(test_pipe(null))
/

第六步:建構腳手架(ROR)

ruby script/generate controller sample
ruby script/generate model sample

  


第七步:修改控制器(ROR)


#/app/controllers/sample_controller
class SampleController < ApplicationController
scaffold :sample
def sample
sql="select name, job from table(test_pipe("+ params[:id] + "))"
unless params[:id].nil?
samples=Sample.find_by_sql(sql)   
@sample=samples[0]
end
end
end

第八步:創建模板(ROR)
  app/views/sample/sample.rhtml
  

<h1> Name of party</h1>
<h2> <%= @sample.name+": "+ @sample.job %> </h2>
<FORM ACTION="" METHOD=GET>
<table>
<tr><td>Party id:  </td><td><input type=text name=id></td></tr>
<tr><td colspan=2><input type=submit value="go"></td></tr>
</table>
</form>

  
  試一下:http://localhost:3000/sample/sample?id=7698
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-248597-1-1.html 上篇帖子: 转:oracle执行计划的一些概念 下篇帖子: Oracle入库速度测试(Python版)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表