如何从光标中获取记录

时间:2016-01-07 09:54:36

标签: java oracle plsql

我正在尝试使用PL SOL游标从Oracle获取一些记录。这是我的代码,

程序参数:

FOR I IN 1 .. PT_CLAIMS.LAST LOOP

        SELECT SEQ_TB_CLIAM.NEXTVAL INTO CLAIM_ID FROM DUAL;


        INSERT INTO TL_CLAIMS
        (
            CLAIM_ID,
            CLAIM_USER,
            CLAMIANT_ID
        )
        VALUES(
            CLAIM_ID,
            PT_CLAIMS(I).USER_ID,
            PT_CLAIMS(I).CLAMIANT_ID
        );

        OPEN PO_CLAIMS_CUSROR FOR
            SELECT CLAIM_ID AS CALIM_ID FROM DUAL; 


end loop;

迭代代码:

(-1000, 1000)

我在java中使用Out游标。但每当我使用ResultSet迭代out游标时,我只获得一条记录。

如何在循环中将值添加到游标。

3 个答案:

答案 0 :(得分:4)

每次循环IN表内容时,都会重新打开OUT sys_refcursor。每次丢弃前一个refcursor并创建一个新的refcursor。 (希望Oracle正在后台正确清理被遗弃的那些)。

当循环退出时,OUT参数的声明ID对应于IN表中的最后一个条目。您没有将每个声明ID添加到单个OUT refcursor中 - 您不能这样做。

您可以维护生成的ID的本地表,然后在循环之后从该本地表打开OUT游标。或者您可以在forall循环中使用单个insert语句替换循环,以允许您使用returning bulk collect into

create procedure p42(pt_claims in claim_bean_tab,
  po_claims_cursor out sys_refcursor)
as
  l_claim_ids sys.odcinumberlist;
begin
  forall i in 1..pt_claims.count
    insert into tl_claims(claim_id, claim_user_id, claimant_id)
    values (seq_tb_claim.nextval, pt_claims(i).user_id, pt_claims(i).claimant_id)
    returning claim_id bulk collect into l_claim_ids;

  open po_claims_cursor for
    select column_value from table(l_claim_ids);
end;
/

这使用了一个预定义的类型,它是一个数字的变种;因为它是一种SQL类型,它可以与table()一起使用(作为table collection expression)。

SQL小提琴似乎再次被打破,所以一个完整的例子:

create type claim_bean as object (user_id number, claimant_id number);
/

create type claim_bean_tab as table of claim_bean;
/

create table tl_claims (claim_id number, claim_user_id number, claimant_id number)
/

create sequence seq_tb_claim;
/

create procedure p42(pt_claims in claim_bean_tab,
  po_claims_cursor out sys_refcursor)
as
  l_claim_ids sys.odcinumberlist;
begin
  forall i in 1..pt_claims.count
    insert into tl_claims(claim_id, claim_user_id, claimant_id)
    values (seq_tb_claim.nextval, pt_claims(i).user_id, pt_claims(i).claimant_id)
    returning claim_id bulk collect into l_claim_ids;

  open po_claims_cursor for
    select column_value from table(l_claim_ids);
end;
/

set serveroutput on
declare
  l_claims claim_bean_tab;
  l_claims_cursor sys_refcursor;
  l_claim_id tl_claims.claim_id%type;
begin
  l_claims := new claim_bean_tab();
  l_claims.extend(3);
  l_claims(1) := new claim_bean(42, 123);
  l_claims(2) := new claim_bean(57, 456);
  l_claims(3) := new claim_bean(13, 789);

  p42(l_claims, l_claims_cursor);
  loop
    fetch l_claims_cursor into l_claim_id;
    exit when l_claims_cursor%notfound;
    dbms_output.put_line('Got claim ID from cursor: ' || l_claim_id);
  end loop;
  close l_claims_cursor;
end;
/

select * from tl_claims
/

PL/SQL procedure successfully completed.

Got claim ID from cursor: 1
Got claim ID from cursor: 2
Got claim ID from cursor: 3

答案 1 :(得分:2)

这是因为您要从变量中提取声明ID,如果要拉出表中插入的所有声明ID,请使用 pw.print(ss); 。如果要拉出表中存在的所有CLAIM_ID,则必须在循环外部打开游标。

select claim_id from TL_CLAIMS

UPDATE:或者,如果您想获取代码中生成的所有声明ID的列表,那么您可以编写类似的内容。

FOR I IN 1 .. PT_CLAIMS.LAST LOOP

        SELECT SEQ_TB_CLIAM.NEXTVAL INTO CLAIM_ID FROM DUAL;


              INSERT INTO TL_CLAIMS
              (
                  CLAIM_ID,
                  CLAIM_USER,
                  CLAMIANT_ID
              )
              VALUES(
              CLAIM_ID,
              PT_CLAIMS(I).USER_ID,
              PT_CLAIMS(I).CLAMIANT_ID
              );

end loop;

OPEN PO_CLAIMS_CUSROR FOR
SELECT CLAIM_ID FROM TL_CLAIMS; 
  

PS:此处的条件是没有来自另一个会话的同时呼叫。

答案 2 :(得分:0)

SELECT CLAIM_ID AS CALIM_ID FROM DUAL; 总是返回一行,因为DUAL只有一行。因此PO_CLAIMS_CUSROR返回一行是预期的行为。