如何在选择查询中使用光标字段

时间:2017-01-16 07:39:00

标签: oracle plsql cursor

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

我有一个如下实现,

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 - “确切的提取返回超过请求的行数”
  *原因:精确提取中指定的数字小于返回的行数   *操作:重写查询或更改请求的行数

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

谢谢。

3 个答案:

答案 0 :(得分:0)

行中的

错误:

  

将curStr从PER_PEOPLE_GROUPS中选择到attValue;

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

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

答案 1 :(得分:0)

问题在于选择。不知道为什么会出现这种情况。光标的值在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 :(得分:0)

此查询没有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. 使用简单作业flexTable(flexTable.count) := (TABLE_TYPE_SAMPLE(cur_recd.colA))
  4. 替换SELECT

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