动态Ref Cursor的定义与调用

2024-04-13 12:32
文章标签 动态 定义 调用 ref cursor

本文主要是介绍动态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;

 

 

这篇关于动态Ref Cursor的定义与调用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/900146

相关文章

在C#中调用Python代码的两种实现方式

《在C#中调用Python代码的两种实现方式》:本文主要介绍在C#中调用Python代码的两种实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#调用python代码的方式1. 使用 Python.NET2. 使用外部进程调用 Python 脚本总结C#调

SpringCloud之LoadBalancer负载均衡服务调用过程

《SpringCloud之LoadBalancer负载均衡服务调用过程》:本文主要介绍SpringCloud之LoadBalancer负载均衡服务调用过程,具有很好的参考价值,希望对大家有所帮助,... 目录前言一、LoadBalancer是什么?二、使用步骤1、启动consul2、客户端加入依赖3、以服务

Vue 调用摄像头扫描条码功能实现代码

《Vue调用摄像头扫描条码功能实现代码》本文介绍了如何使用Vue.js和jsQR库来实现调用摄像头并扫描条码的功能,通过安装依赖、获取摄像头视频流、解析条码等步骤,实现了从开始扫描到停止扫描的完整流... 目录实现步骤:代码实现1. 安装依赖2. vue 页面代码功能说明注意事项以下是一个基于 Vue.js

mybatis-plus 实现查询表名动态修改的示例代码

《mybatis-plus实现查询表名动态修改的示例代码》通过MyBatis-Plus实现表名的动态替换,根据配置或入参选择不同的表,本文主要介绍了mybatis-plus实现查询表名动态修改的示... 目录实现数据库初始化依赖包配置读取类设置 myBATis-plus 插件测试通过 mybatis-plu

讯飞webapi语音识别接口调用示例代码(python)

《讯飞webapi语音识别接口调用示例代码(python)》:本文主要介绍如何使用Python3调用讯飞WebAPI语音识别接口,重点解决了在处理语音识别结果时判断是否为最后一帧的问题,通过运行代... 目录前言一、环境二、引入库三、代码实例四、运行结果五、总结前言基于python3 讯飞webAPI语音

基于Canvas的Html5多时区动态时钟实战代码

《基于Canvas的Html5多时区动态时钟实战代码》:本文主要介绍了如何使用Canvas在HTML5上实现一个多时区动态时钟的web展示,通过Canvas的API,可以绘制出6个不同城市的时钟,并且这些时钟可以动态转动,每个时钟上都会标注出对应的24小时制时间,详细内容请阅读本文,希望能对你有所帮助...

Vue中动态权限到按钮的完整实现方案详解

《Vue中动态权限到按钮的完整实现方案详解》这篇文章主要为大家详细介绍了Vue如何在现有方案的基础上加入对路由的增、删、改、查权限控制,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、数据库设计扩展1.1 修改路由表(routes)1.2 修改角色与路由权限表(role_routes)二、后端接口设计

C#集成DeepSeek模型实现AI私有化的流程步骤(本地部署与API调用教程)

《C#集成DeepSeek模型实现AI私有化的流程步骤(本地部署与API调用教程)》本文主要介绍了C#集成DeepSeek模型实现AI私有化的方法,包括搭建基础环境,如安装Ollama和下载DeepS... 目录前言搭建基础环境1、安装 Ollama2、下载 DeepSeek R1 模型客户端 ChatBo

Java中的Cursor使用详解

《Java中的Cursor使用详解》本文介绍了Java中的Cursor接口及其在大数据集处理中的优势,包括逐行读取、分页处理、流控制、动态改变查询、并发控制和减少网络流量等,感兴趣的朋友一起看看吧... 最近看代码,有一段代码涉及到Cursor,感觉写法挺有意思的。注意是Cursor,而不是Consumer

前端 CSS 动态设置样式::class、:style 等技巧(推荐)

《前端CSS动态设置样式::class、:style等技巧(推荐)》:本文主要介绍了Vue.js中动态绑定类名和内联样式的两种方法:对象语法和数组语法,通过对象语法,可以根据条件动态切换类名或样式;通过数组语法,可以同时绑定多个类名或样式,此外,还可以结合计算属性来生成复杂的类名或样式对象,详细内容请阅读本文,希望能对你有所帮助...