【问题标题】:How to use cursor field in a select query如何在选择查询中使用游标字段
【发布时间】:2017-05-31 00:07:16
【问题描述】:

我在这里尝试使用光标,我想知道如何访问选择列中的光标字段?

我有一个实现如下,

create or replace TYPE  "TABLE_TYPE_SAMPLE" AS OBJECT(
   ENTITY_NAME            VARCHAR2(100)
);

 

create or replace TYPE  "TABLE_SAMPLE" AS TABLE OF TABLE_TYPE_SAMPLE; 

 

    CREATE OR REPLACE FUNCTION segmentFields(
   txnId            VARCHAR2)
    RETURN TABLE_SAMPLE
IS
attValue VARCHAR2(20);
 curStr   VARCHAR2(20);

  flexTable  TABLE_SAMPLE := TABLE_TYPE_SAMPLE();

 CURSOR cur_seg
 IS
   (SELECT colA
   FROM table1 -- (table name has column colA)
   WHERE id = txnId
   );
BEGIN
 FOR cur_recd IN cur_seg
 LOOP
   curStr := cur_recd.colA;
   SELECT curStr into attValue FROM PER_PEOPLE_GROUPS;

flexTable.EXTEND;
   flexTable(flexTable.count) := (TABLE_TYPE_SAMPLE(attValue)) ;
 END LOOP;
RETURN flexTable;
END; 

函数执行没有错误。但是当我尝试在查询下运行时

select * from table(segmentFields(480));

我收到以下错误,

ORA-01422:精确提取返回的行数多于请求的行数
ORA-06512:在“SEGMENTFIELDS”,第 19 行
01422. 00000 - “精确提取返回的行数超过了请求的行数”
*原因:exact fetch 中指定的数量小于返回的行数。
*操作:重写查询或更改请求的行数

我想了解一下,这个实现有什么问题。

谢谢。

【问题讨论】:

    标签: oracle plsql cursor


    【解决方案1】:

    问题在于选择进入。不知道为什么首先存在。光标的值在 cur_recd.cola 中可用,您可以直接使用它。

    create or replace function segmentfields(txnid varchar2) return table_sample is
    
       flextable table_sample := table_type_sample();
    
       cursor cur_seg is(
          select cola
            from table1 -- (table name has column colA)
           where id = txnid);
    begin
       for cur_recd in cur_seg
       loop
          flextable.extend;
          flextable(flextable.count) := (table_type_sample(cur_recd.cola));
       end loop;
       return flextable;
    end;
    

    【讨论】:

      【解决方案2】:

      此查询没有 WHERE 子句:

      SELECT curStr into attValue FROM PER_PEOPLE_GROUPS;
      

      这意味着它将返回 PER_PEOPLE_GROUPS 中所有行的命中。 SELECT ... INTO 构造填充单个变量,因此需要一个恰好返回一行的查询。 ORA-01422 消息表明您没有执行精确提取,显然是因为 PER_PEOPLE_GROUPS 有不止一行。

      几种可能的解决方案,具体取决于您要实现的目标:

      1. 添加某种限制,以便您只从 PER_PEOPLE_GROUPS 返回一行。
      2. 改为使用 BULK COLLECT 填充任何数组。
      3. 将 SELECT 替换为简单的赋值 flexTable(flexTable.count) := (TABLE_TYPE_SAMPLE(cur_recd.colA))

      从表面上看,放弃 SELECT 似乎是最好的选择,因为它不会为您提供任何信息。但是,您似乎也可能正在尝试实现一些未在发布的代码中表达的其他业务逻辑,因此您可能需要进行一些更改。

      【讨论】:

      • 您好 APC,您对 BULK INTO 的建议奏效了。类型segments_aat 是cur_seg%ROWTYPE 的表; l_columns 段_aat; SELECT curStr BULK COLLECT into l_columns FROM PER_PEOPLE_GROUPS;
      • @SatyajeethT - 如果此答案对您有用,请投票和/或接受它作为正确答案。此类行动提高了 SO 作为未来寻求者资源的质量。
      【解决方案3】:

      行错误:

      从 PER_PEOPLE_GROUPS 中选择 curStr 到 attValue;

      执行代码? PER_PEOPLE_GROUPS 中有多少行?

      error indicates that more than one。您可能需要在 where 子句中添加条件?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-06-10
        • 1970-01-01
        • 1970-01-01
        • 2012-06-12
        • 2021-05-07
        • 1970-01-01
        • 2011-07-19
        • 1970-01-01
        相关资源
        最近更新 更多