动态Ref Cursor的定义与调用

1.定义:

type ref_cur is ref cursor;

2.动态cursor作为out参数 存储过程的实现

举个最简单的例子,根据table name动态获取cursor

PROCEDURE P_GET_CUR(I_TABLE_NAME IN VARCHAR2, O_REF_CUR OUT REF_CUR) AS

BEGIN

IF UPPER(I_TABLE_NAME) = ‘T_BANK_ACCOUNT‘ THEN

OPEN O_REF_CUR FOR

SELECT BANK_ACCOUNT

FROM T_BANK_ACCOUNT

WHERE BANK_ACCOUNT IS NOT NULL;

ELSIF UPPER(I_TABLE_NAME) = ‘T_FB_PAYMENT_JP‘ THEN

OPEN O_REF_CUR FOR

SELECT BANK_ACCOUNT

FROM T_FB_PAYMENT_JP

WHERE BANK_ACCOUNT IS NOT NULL;

END IF;

END P_GET_CUR;

3.调用,用项目中mask 口座番号的功能为例,跟大家分享下:

procedure p_bank_acco_mask(i_table_name in varchar2,

i_coulumn in varchar,

o_error_str in out varchar2,

o_result in out number,

m_has_exception in out boolean) as

v_update_sql varchar(800);

v_update_sql2 varchar(800);

i int := 1;

v_bank_account VARCHAR2(50);

v_bank_account_new VARCHAR2(50);

v_char VARCHAR(1);

v_bank_account_curs ref_cur;

v_select_sql VARCHAR2(800);

begin

o_result := PKG_LS_PUB_CODE_CST.BATCH_RESULT__SUCCESS;

BEGIN

p_get_cur(i_table_name,v_bank_account_curs);

savepoint point;

v_update_sql2 := ‘‘;

LOOP

FETCH v_bank_account_curs INTO v_bank_account;

EXIT WHEN v_bank_account_curs%NOTFOUND;

BEGIN

for i in 1 .. length(v_bank_account) LOOP

v_select_sql:=‘SELECT SUBSTR(‘||i_coulumn||‘,‘||i||‘,1) from ‘|| i_table_name ||‘ where ‘||i_coulumn||‘=‘‘‘||v_bank_account||‘‘‘ and rownum<=1‘;

v_char:=f_get_char(v_select_sql);

IF v_char IS NULL THEN

RETURN;

END IF;

IF v_char=‘2‘ OR v_char=‘3‘ THEN--1

v_char:=‘1‘;

ELSIF v_char=‘5‘ OR v_char=‘6‘ THEN--4

v_char:=‘4‘;

ELSIF v_char=‘8‘ OR v_char=‘9‘ THEN--7

v_char:=‘7‘;

END IF;

v_bank_account_new:=v_bank_account_new||v_char;

END LOOP;

--should support bank_code=‘9900‘

if i_table_name = ‘T_DT_ACCOUNT_JP‘ then

v_update_sql := ‘ update ‘ || i_table_name || ‘ set ‘ || i_coulumn ||

‘ = decode( Head_Bank_Code ‘  || ‘,‘ ||

‘‘‘9900‘‘‘ || ‘,‘ || ‘‘‘12340-01111281‘‘‘ || ‘,‘ ||

v_bank_account_new ||‘ ) where‘ || i_coulumn ||‘=‘‘‘|| v_bank_account||‘‘‘‘;

elsif i_table_name = ‘T_CASH_BANK‘ then

v_update_sql := ‘ update ‘ || i_table_name || ‘ set ‘ || i_coulumn ||

‘ = decode( CASH_BANK ‘  || ‘,‘ ||

‘‘‘9900‘‘‘ || ‘,‘ || ‘‘‘12340-01111281‘‘‘ || ‘,‘ ||

v_bank_account_new ||‘ ) where‘ || i_coulumn ||‘=‘‘‘|| v_bank_account||‘‘‘‘;

elsif i_table_name = ‘T_CASH_BANK_LOG‘ then

v_update_sql := ‘ update ‘ || i_table_name || ‘ set ‘ || i_coulumn ||

‘ = decode( CASH_BANK ‘  || ‘,‘ ||

‘‘‘9900‘‘‘ || ‘,‘ || ‘‘‘12340-01111281‘‘‘ || ‘,‘ ||

v_bank_account_new ||‘ ) where‘ || i_coulumn ||‘=‘‘‘|| v_bank_account||‘‘‘‘;

elsif i_table_name = ‘T_AGM_AGENT‘ then

v_update_sql := ‘ update ‘ || i_table_name ||

‘ set COMM_ACCOUNT = ‘ || v_bank_account_new ||‘‘ ||

‘ where COMM_PAY_BANK_CODE <> ‘‘9900‘‘ and ‘|| i_coulumn ||‘=‘‘‘|| v_bank_account||‘‘‘‘;

v_update_sql2 := ‘ update ‘ || i_table_name ||

‘ set COMM_PAY_BRANCH_CODE =‘‘12340‘‘, ‘ ||

‘     COMM_ACCOUNT = ‘‘01111281‘‘  ‘ ||

‘ where COMM_PAY_BANK_CODE = ‘‘9900‘‘‘;

elsif i_table_name = ‘T_SHOSHIHARAIRIREKIJOUHOU_TBL‘ then

v_update_sql := ‘ update ‘ || i_table_name || ‘ set ‘ || i_coulumn ||

‘ = decode( substr(BANK_ACCOUNT_NO,2,4) ‘  ||

‘,‘ || ‘‘‘9900‘‘‘ || ‘,‘ || ‘‘‘12340-01111281‘‘‘ ||

‘,‘ || v_bank_account_new ||‘ ) where‘ || i_coulumn ||‘=‘‘‘|| v_bank_account||‘‘‘‘;

elsif i_table_name = ‘T_NYUSHUTUKINRIREKIJOUHOU‘ then

v_update_sql := ‘ update ‘ || i_table_name || ‘ set ‘ || i_coulumn ||

‘ = decode( substr(KOUZA_NO,2,4) ‘  ||

‘,‘ || ‘‘‘9900‘‘‘ || ‘,‘ || ‘‘‘12340-01111281‘‘‘ ||

‘,‘ || v_bank_account_new ||‘ ) where‘ || i_coulumn ||‘=‘‘‘|| v_bank_account||‘‘‘‘;

elsif i_table_name = ‘T_ACCOUNT_APPLY_TBL‘ then

v_update_sql := ‘ update ‘ || i_table_name || ‘ set ‘ || i_coulumn ||

‘ = decode( substr(ACCOUNT_NO,1,4) ‘  ||

‘,‘ || ‘‘‘9900‘‘‘ || ‘,‘ || ‘‘‘12340-01111281‘‘‘ ||

‘,‘ || v_bank_account_new ||‘ ) where‘ || i_coulumn ||‘=‘‘‘|| v_bank_account||‘‘‘‘;

elsif i_table_name = ‘T_LSIF_OTHERS‘ then

v_update_sql := ‘ update ‘ || i_table_name || ‘ set KOUZAINO = ‘ ||

v_bank_account_new ||‘‘ || ‘ where BANKCN <> ‘‘9900‘‘ and ‘|| i_coulumn ||‘=‘‘‘|| v_bank_account||‘‘‘‘;

v_update_sql2 := ‘ update ‘ || i_table_name ||

‘ set SITENCNJYO =‘‘123‘‘, ‘ ||

‘     SITENCNKA = ‘‘40‘‘,  ‘ ||

‘     KOUZAINO = ‘‘01111281‘‘  ‘ ||

‘ where BANKCN = ‘‘9900‘‘‘;

elsif i_table_name = ‘T_LSIF_GETUMATU_NENMATU_MASTER‘ then

v_update_sql := ‘ update ‘ || i_table_name || ‘ set KOUZAINO = ‘ ||

v_bank_account_new ||‘‘ || ‘ where BANKCN <> ‘‘9900‘‘ and ‘|| i_coulumn ||‘=‘‘‘|| v_bank_account||‘‘‘‘;

v_update_sql2 := ‘ update ‘ || i_table_name ||

‘ set SITENCN =‘‘12340‘‘, ‘ ||

‘     KOUZAINO = ‘‘01111281‘‘  ‘ ||

‘ where BANKCN = ‘‘9900‘‘‘;

elsif i_table_name = ‘T_LSIF_KAIKEI‘ then

v_update_sql := ‘ update ‘ || i_table_name || ‘ set WUZANO = ‘ ||

v_bank_account_new ||‘‘ ||

‘ where GANKOWUMEYISHOUWUCN <> ‘‘9900‘‘ and ‘|| i_coulumn ||‘=‘‘‘|| v_bank_account||‘‘‘‘;

v_update_sql2 := ‘ update ‘ || i_table_name ||

‘ set SHITEYINMEYISYOUWUCN =‘‘123‘‘, ‘ ||

‘     WUZANO = ‘‘01111281‘‘  ‘ ||

‘ where GANKOWUMEYISHOUWUCN = ‘‘9900‘‘‘;

elsif i_table_name = ‘T_LSIF_IDOUEXTR‘ and i_coulumn = ‘KOUZAINO_ZEN‘ then

v_update_sql := ‘ update ‘ || i_table_name ||

‘ set KOUZAINO_ZEN = ‘ || v_bank_account_new ||‘‘ ||

‘ where GINKOUCN_ZEN <> ‘‘9900‘‘ and ‘|| i_coulumn ||‘=‘‘‘|| v_bank_account||‘‘‘‘;

v_update_sql2 := ‘ update ‘ || i_table_name ||

‘ set SHITENCNE_ZEN =‘‘123‘‘, ‘ ||

‘     SHITENCNGE_ZEN = ‘‘40‘‘,  ‘ ||

‘     KOUZAINO_ZEN = ‘‘01111281‘‘  ‘ ||

‘ where GINKOUCN_ZEN = ‘‘9900‘‘‘;

elsif i_table_name = ‘T_LSIF_IDOUEXTR‘ and i_coulumn = ‘KOUZAINO_GO‘ then

v_update_sql := ‘ update ‘ || i_table_name || ‘ set KOUZAINO_GO = ‘ ||

v_bank_account_new ||‘‘ ||

‘ where GINKOUCN_GO <> ‘‘9900‘‘ and ‘|| i_coulumn ||‘=‘‘‘|| v_bank_account||‘‘‘‘;

v_update_sql2 := ‘ update ‘ || i_table_name ||

‘ set SHITENCNE_GO =‘‘123‘‘, ‘ ||

‘     SHITENCNGE_GO = ‘‘40‘‘,  ‘ ||

‘     KOUZAINO_GO = ‘‘01111281‘‘  ‘ ||

‘ where GINKOUCN_GO = ‘‘9900‘‘‘;

elsif i_table_name = ‘T_DIAGNOSIS_CHARGE_DATA‘ then

v_update_sql := ‘ update ‘ || i_table_name || ‘ set ACCOUNT_NO = ‘ ||

v_bank_account_new ||‘‘ || ‘ where BANK_CN <> ‘‘9900‘‘ and ‘|| i_coulumn ||‘=‘‘‘|| v_bank_account||‘‘‘‘;

v_update_sql2 := ‘ update ‘ || i_table_name ||

‘ set BRANCH_CN =‘‘123‘‘, ‘ ||

‘     ACCOUNT_NO = ‘‘01111281‘‘  ‘ ||

‘ where BANK_CN = ‘‘9900‘‘‘;

elsif i_table_name = ‘T_IFE_MONTHLY_GETUMATU_MASTER‘ then

v_update_sql := ‘ update ‘ || i_table_name || ‘ set ‘ || i_coulumn ||

‘ = decode( BANKCN ‘  || ‘,‘ ||

‘‘‘9900‘‘‘ || ‘,‘ || ‘‘‘12340-01111281‘‘‘ || ‘,‘ ||

v_bank_account_new ||‘ ) where ‘|| i_coulumn ||‘=‘‘‘|| v_bank_account||‘‘‘‘;

else

v_update_sql := ‘ update ‘ || i_table_name || ‘ set ‘ || i_coulumn ||

‘ = decode( bank_code ‘  || ‘,‘ ||

‘‘‘9900‘‘‘ || ‘,‘ || ‘‘‘12340-01111281‘‘‘ || ‘,‘ ||

v_bank_account_new ||‘ ) where ‘|| i_coulumn ||‘=‘‘‘|| v_bank_account||‘‘‘‘;

end if;

v_bank_account_new:=‘‘;--clear data

execute immediate v_update_sql;

if v_update_sql2 is not null then

execute immediate v_update_sql2;

end if;

pkg_pub_scd_ci.p_batch_commit();

EXCEPTION

when others then

rollback to point;

o_result := PKG_LS_PUB_CODE_CST.BATCH_RESULT__FAIL;

o_error_str := i_table_name || ‘,‘;

pkg_pub_scd_ci.p_log_error(‘p_bank_acco_mask ,failed to mask table:‘ ||

i_table_name || ‘,error info:‘ ||

sqlerrm || ‘-------update SQL=‘ ||

v_update_sql);

m_has_exception := true;

end;

END LOOP;

CLOSE v_bank_account_curs;

END;

end p_bank_acco_mask;

动态创建cursor的函数原理同上,其他带参数的cursor具体可以参考下面的:

--procedure返回记录集:

----------------------声明一个Package--------------

CREATE OR REPLACE PACKAGE pkg_test

AS

TYPEmyrctypeIS REF CURSOR;

PROCEDURE get_r(p_id NUMBER,p_rc OUT myrctype); --Package中声明名为get 的Procedure(只有接口没内容)

END pkg_test;

-----------------声明Package Body,即上面Package中的内容,包括Procedure get---------------------

CREATE OR REPLACE PACKAGE BODY pkg_test

AS

PROCEDURE get_r(p_id NUMBER,p_rc OUT myrctype)

IS

sqlstr VARCHAR2 (500);

BEGIN

IF p_id = 0 THEN

OPEN p_rc FOR

SELECT ID, NAME, sex, address, postcode, birthday

FROM student;

ELSE

sqlstr :=

‘select id,name,sex,address,postcode,birthday

from student where id=:w_id‘; --w_id是个参数,

--以下 p_rc是个REF CURSOR游标类型,而且是OUT型参数,即可返回一个记录集了。USING p_id就是替换上面SQL中:w_id值拉:)

OPEN p_rc FOR sqlstr USING p_id; 

END IF;

END get;

END pkg_test;

--function返回记录集的例子,原理和上面相同,而是用function的return值来返回记录集。

函数返回记录集:

建立带ref cursor定义的包和包体及函数:

复制代码 代码如下:

CREATE OR REPLACE

package pkg_test as

type myrctype is ref cursor;

function get_r(intID number) return myrctype;

end pkg_test;

/

CREATE OR REPLACE

package body pkg_test as

--函数体

function get_r(intID number) return myrctype is

rc myrctype; --定义ref cursor变量

sqlstr varchar2(500);

begin

if intID=0 then

--静态测试,直接用select语句直接返回结果

open rc for select id,name,sex,address,postcode,birthday from student;

else

--动态sql赋值,用:w_id来申明该变量从外部获得

sqlstr := ‘select id,name,sex,address,postcode,birthday from student where id=:w_id‘;

--动态测试,用sqlstr字符串返回结果,用using关键词传递参数

open rc for sqlstr using intid;

end if;

return rc;

end get;

end pkg_test;

时间: 2024-10-05 06:05:30

动态Ref Cursor的定义与调用的相关文章

PLSQL中显示Cursor、隐示Cursor、动态Ref Cursor差别

一.显式cursor 显式是相对与隐式cursor而言的,就是有一个明白的声明的cursor.显式游标的声明类似例如以下(具体的语法參加plsql ref doc ): cursor cursor_name (parameter list) is select ... 游标从declare.open.fetch.close是一个完整的生命旅程. 当然了一个这种游标是能够被多次open进行使用的,显式cursor是静态cursor,她的作用域是全局的,但也必须明确,静态cursor也仅仅有pl/s

PLSQL中显示Cursor、隐示Cursor、动态Ref Cursor区别

一.显式cursor 显式是相对与隐式cursor而言的,就是有一个明确的声明的cursor.显式游标的声明类似如下(详细的语法参加plsql ref doc ): cursor cursor_name (parameter list) is select ... 游标从declare.open.fetch.close是一个完整的生命旅程.当然了一个这样的游标是可以被多次open进行使用的,显式cursor是静态cursor,她的作用域是全局的,但也必须明白,静态cursor也只有pl/sql代

REF CURSOR 总结

REF 游标:REF游标又称为动态游标,在运行时使不同的语句与之关联,动态关联结果集的临时对象,即在运行的时候动态决定执行查询.REF游标可以使用游标变量.游标变量:游标变量是一种引用REF游标类型的变量,只想动态关联的结果集.游标变量的类型:1.具有约束的游标变量,具有返回类型的游标变量也称为强游标.2.无约束的游标变量,没有返回类型的游标变量也称为弱游标.REF游标的作用:实现程序间传递结果集的功能,利用REF cursor 也可以实现bulk sql 从而提高sql性能.静态游标和REF游

Oracle ref cursor和sys_refcursor

1. 自定义 ref cursor 和 sys_refcursor; 2. sys_refcursor 做为参数传递结果集; 3. ref cursor 做为参数传递结果集;   1. 自定义 ref cursor 和 sys_refcursor: declare type df_ref is ref cursor; --定义 ref cursor rf df_ref; --声明 rf 是df_ref ename varchar2(30); begin open rf for 'select e

Report_报表中Ref Cursor数据源的概念和用法(案例)

2014-06-22 BaoXinjian 一.摘要 在Report Builder中,有两种数据源取法,一种是基于SQL的,另外一种就是基于Ref Cursor的写法 Ref Cursor在Report Builder 中主要用于一些公用的查询会使用到 比如有多个Report可能会用到同一段SQL或者类似SQL,一般会将这个SQL独立出来作为Ref Cursor放在Package中 当Report调用时,就可以通过调用package中的ref cursor实现查询,而不是讲这段SQL每个rep

oracle 存储过程及REF CURSOR的使用

基本使用方法及示例 1.基本结构: CREATE OR REPLACE PROCEDURE 存储过程名字 (参数1 IN NUMBER,参数2 IN NUMBER) AS 变量1 INTEGER :=0; 变量2 DATE; BEGIN END 存储过程名字 2.无参形式的procedure: --无参procedure create or replace procedure pro_no_param is begin dbms_output.put_line('the procedure wi

Entity Framework 5.0.0 Function Import 以及 Implicit REF CURSOR Binding

源代码 概要:1,明如何使用Entity Framework中的function import功能. 2,说明如何使用ODP.NET的隐式REF CURSOR绑定(implicit REF CURSOR binding). 环境以及工具: Windows 10 企业版 Microsoft Visual Studio Enterprise 2015 Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 .NET Framework 4.

bulk collect 以及ref cursor使用

declare ---定义一个ref游标 type empcurtyp is ref cursor; ---定义一个table类型 type idlist is table of emp.empno%type; ---定义一个table类型 type namelist is table of emp.ename%type; ---定义一个table类型 type sallist is table of emp.sal%type; ---定义一个ref cursor类型的变量 emp_cv emp

函数 定义与调用

为什么要用函数 函数的定义与调用 函数的返回值 函数的参数 本章小结 返回顶部 为什么要用函数 现在python届发生了一个大事件,len方法突然不能直接用了... 然后现在有一个需求,让你计算'hello world'的长度,你怎么计算? 这个需求对于现在的你其实不难,我们一起来写一下. s1 = "hello world" length = 0 for i in s1: length = length+1 print(length) 好了,功能实现了,非常完美.然后现在又有了一个需