oracle FOR LOOP 不在 SYS_REFCURSOR 中迭代

2024-03-08

程序如下:

  1. 打开游标,然后通过批量收集获取选择查询的输出。
  2. 问题是所有 ID 都存储在批量收集中,但我无法使用批量收集变量作为输入来循环第二个选择查询,它只考虑第一个 ID,而不是全部。
  3. 输出应该是 SYS_REFCURSOR,请说明我在这里缺少什么

表1的测试数据:

ID CURRENCY T_ID
10 GBP PB1
15 GBP RB
20 GBP CC
25 AUD DC

根据 t_id,我获取相应的 ID,然后在进一步的 select for 循环语句中使用这些 ID。

通过 SYS_REFCURSOR 的过程的当前输出:

ID COUNTRY ACCOUNT
10 UK PB1

预期输出:

ID COUNTRY ACCOUNT
10 UK PB1
15 Wales RB
20 SH CC
create or replace procedure myproc (i_id in varchar2, rc out sys_refcursor)
as
    cursor names_cur is
        select id from table1 where currency='GBP' and t_id=i_id;
    names_t names_cur%ROWTYPE;
    type names_ntt is table of names_t%TYPE;
    l_names names_ntt;
begin
    open names_cur;
    fetch names_cur bulk collect into l_names ; --Inside l_names (10,15 & 20) would be stored 
    close names_cur;
--iSSUE IS WITH BELOW FOR LOOP
    for cur in l_names.first..l_names.last loop
        open rc for --For the below select I want to iterate l_names so for the above scenario it should iterate thrice

        select s.id,s.country,s.account from table2 s where s.id=l_names(cur).id;
    end loop;

end myproc;

请注意以下扩展评论:

也许问题的核心是对光标是什么的误解。它不是一个装满记录的容器,而是基于单个 SQL 查询在某个时间点的结果集规范。所以如果你

open rc for select id from table1;

并通过rc返回到调用者,您没有传递任何数据,而是传递一个指向包含准备好的查询的私有内存区域的指针。您不推送结果,而是调用者拉取结果。它就像调用者将执行以获取行的程序。您无法再打开它来添加另一行,我认为这正是您希望做的。


要在过程中的游标中使用集合,必须将集合类型创建为单独的架构对象(当然,您可以在其他过程中重用集合类型,因此它并不像听起来那么严格)。

如果您无法创建类型,请查看已有哪些类型可以使用:

select owner, type_name
from   all_coll_types t
where  t.coll_type = 'TABLE'
and    t.elem_type_name = 'NUMBER';

例如:

create or replace type number_tt as table of number;

create table table1 (id primary key, currency, t_id) as
    select 10, 'GBP', 'PB1' from dual union all
    select 15, 'GBP', 'RB' from dual union all
    select 20, 'GBP', 'CC' from dual union all
    select 25, 'AUD', 'DC' from dual;

create table table2 (id,country,account) as
    select 10, 'UK', 'PB1' from dual union all
    select 15, 'Wales', 'RB' from dual union all
    select 20, 'SH', 'CC' from dual;

现在程序可以是:

create or replace procedure myproc
    ( rc out sys_refcursor)
as
    l_names number_tt;
begin
    select id bulk collect into l_names
    from   table1
    where  currency = 'GBP';

    open rc for
        select t.id,t.country,t.account from table2 t
        where  t.id member of l_names;
end myproc;

光标输出:

        ID COUNT ACC
---------- ----- ---
        10 UK    PB1
        15 Wales RB
        20 SH    CC

(我删除了i_id参数在你的程序中,因为我不清楚你想如何使用它。)

据推测,这是实际问题的简化版本,因为就目前情况而言,您可以使用第一个查询作为子查询,并且不需要该集合:

create or replace procedure myproc
    ( rc out sys_refcursor)
as
begin
    open rc for
        select t.id,t.country,t.account from table2 t
        where  t.id in
               ( select id 
                 from   table1
                 where  currency = 'GBP' );
end myproc;

或者只是加入它,正如 Littlefoot 建议的那样:

create or replace procedure myproc
    ( rc out sys_refcursor)
as
begin
    open rc for
        select t2.id, t2.country, t2.account
        from   table1 t1
               join table2 t2 on t2.id = t1.id
        where  t1.currency = 'GBP';
end myproc;

然而,您对这个答案评论说您不能这样做,因为您的要求似乎是通过一个集合、一个循环、一些胶带、两只猫和一个融合发生器来完成。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

oracle FOR LOOP 不在 SYS_REFCURSOR 中迭代 的相关文章

随机推荐

  • Python Pandas:使用参数将多个函数传递给 agg()

    我正在努力弄清楚如何组合 pandas 的两种不同语法dataframe agg 功能 采用这个简单的数据框 df pd DataFrame A group1 group1 group2 group2 group3 group3 B 10
  • Quartz.Net IJobFactory 接口中 ReturnJob 的用途是什么

    我使用简单的注入器作为 IOC 容器 但我不清楚它的责任是什么返回工作 我想知道我该如何继续 这是我到目前为止所做的代码 public class SimpleInjectorJobFactory IJobFactory private r
  • 接口和类方法的注释应该如何不同

    在使用 C 中的 Web 客户端软件工厂 WCSF 开发 ASP net Web 应用程序时 我遇到了这种困境 同样的情况也适用于其他平台和语言 我的情况是这样的 我正在定义一个我基于 WCSF 范例查看每个网页 用户控件的界面 然后让页面
  • 在 SQLServer 作为 sessionState 模式的 ASP.NET 中,如何处理会话对象超时?

    当您将 SQL Server 设置为 ASP NET 应用程序中的状态处理程序时 如何或在何处处理会话超时 是 NET框架在从数据库加载会话对象后判断对象是否过期 还是SQL Server本身负责处理这个问题 我怀疑 甚至考虑 后一种可能性
  • 如何在 Perl 中使用反引号捕获两个不同变量中的 STDOUT 和 STDERR

    假设我想从带有反引号的脚本中运行外部程序 同时我想捕获 STDOUT 和 STDERR 但在两个不同的变量中 我怎样才能做到这一点 例如 如果我运行这个脚本 my cmd snmpwalk v version c community hos
  • python 只读类属性

    有没有办法在Python中创建只读类属性 前任 在Unity3d中你可以这样做 transform position Vector3 zero Vector3 zero 返回 Vector3 类的实例 其中 x y 和 z 均为 0 这与以
  • IDataErrorInfo:提交页面时进行验证

    我正在创建一个 WPF 应用程序 它将使用IDataErrorInfo数据验证 我的业务对象实现的 我一直在与这个演示来自博客文章 http www codegod de WebAppCodeGod WPF IDataErrorInfo a
  • 根接口属性无法通过 Html 助手中的父接口访问

    我觉得我在这里缺少一些基本的东西 我有2个接口 一种称为 IIdentABLE 它指定 Id 属性的存在 第二个实际上可以是任何可识别的东西 请参阅下面的代码 public interface IIdentifiable Guid Id g
  • 带进度条的 Tkinter GUI

    我有一个简单的 Tk GUI 和一个附加到按钮的函数中的长流程 我想要一个进度条 当我点击按钮时 就像它开始一个漫长的过程一样 我怎样才能做到这一点 这是我当前的代码 from tkinter import Button Tk HORIZO
  • Gradle 测试命令未运行任何测试

    我有一个可以在 Android Studio 上运行的简单测试实现 这个类位于我的项目的 src androidTest 目录中 应用程序测试 java public class ApplicationTest extends Applic
  • 通过开始和结束索引抓取 List 的一部分

    这可能吗 例如 如果我有 List
  • 使用 C、gcc、C99 和宏优化微控制器的简约 OOP

    我经常必须用 C 语言对微控制器进行编程 因为 C 编译器通常不可用 或者由于各种错误而无法编写极小的代码 但很多时候 OOP 语法糖 在使硬件程序封装得更清晰 易于维护方面非常方便 所以我想找出是否有一种方法可以在 C 中执行 OOP 语
  • Objective-C 如何检查字符串是否为空

    所以 我想检查我的数组中是否有该项目 clientDataArray objectForKey ClientCompany is nil temp clientDataArray objectForKey ClientCompany if
  • 如何用PHP生成随机密码?

    或者有没有自动生成随机密码的软件 只需构建一串随机数a z A Z 0 9 或者任何你想要的 直到所需的长度 这是 PHP 中的示例 function generatePassword length 8 chars abcdefghijkl
  • 为restify.js 实现基于令牌的身份验证的最佳方法是什么?

    我正在尝试使用restify js 构建一个RESTful api 但我不想将该api 暴露给所有人 我将使用基于令牌的身份验证 我脑子里的流程是这样的 不知道是否合理 用户将用户名 密码发送到 api 来获取令牌 此令牌应包含在调用所有其
  • Python 对新实例的交替引用

    这些天我一直在玩Python 我意识到Python如何将id 地址 分配给新实例 int和list 的一些有趣的方式 例如 如果我继续使用一个数字 或两个不同的数字 调用 id 函数 它会返回相同的结果 例如 gt gt gt id 123
  • 使用 JSON 键作为嵌套 JSON 中的属性

    我正在 python 2 7 中使用嵌套的类似 JSON 的数据结构 我与一些外国 perl 代码进行交换 我只是想以更Pythonic的方式 处理 这些列表和字典的嵌套结构 所以如果我有这样的结构 a x 4 y 2 3 a 55 b 6
  • 表格视图单元上的步进器(快速)

    我将步进器的出口和操作放入表格视图单元格中 并使用协议委托将其连接到表格视图 当我点击第一行中的步进器时 步进器值在第一行中正常显示 但它也出现在某个随机行中 如何解决这个问题 表格视图单元格 protocol ReviewCellDele
  • WPF 工具包数据网格 - 自定义选项卡

    我有一个包含 3 列的 WPF 工具包 DataGrid 只有第三列允许数据输入 前两列是静态的 文本描述 是否可以控制选项卡和导航 以便选项卡和上下左右按钮将忽略前两列并在第三列的范围内运行 您可以使用以下命令禁用前两列上的制表符IsTa
  • oracle FOR LOOP 不在 SYS_REFCURSOR 中迭代

    程序如下 打开游标 然后通过批量收集获取选择查询的输出 问题是所有 ID 都存储在批量收集中 但我无法使用批量收集变量作为输入来循环第二个选择查询 它只考虑第一个 ID 而不是全部 输出应该是 SYS REFCURSOR 请说明我在这里缺少