oracle—用于获取pl/sql中cursor列中所有值的结果的函数

u7up0aaq  于 2021-08-09  发布在  Java
关注(0)|答案(2)|浏览(351)

我有疑问。现在我有:

create or replace function f_test(par_cat in varchar2) return sys_refcursor is
  l_str varchar2(1000);
  l_rc  sys_refcursor;
begin
  for cur_r in (select cat, kw_crt
                  from (select owner_category cat,
                               substr(PROPERTY_ID, 1, 4) kw_crt,
                               ROW_NUMBER() OVER(PARTITION BY owner_category 
                               ORDER BY owner_category, substr(PROPERTY_ID, 1, 4)) rank
                          from owners)
                 where rank < 3
                   and cat = par_cat) loop
    l_str := 'select * ' || 'from owners ' ||
             'where substr(PROPERTY_ID,1,4) in (' || chr(39) ||
             cur_r.kw_crt || chr(39) || ')' || '  and Owner_category    = ' ||
             chr(39) || cur_r.cat || chr(39);
  end loop;

  open l_rc for l_str;
  return l_rc;
end;
/

哪里

select owner_category cat,
       substr(PROPERTY_ID, 1, 4) kw_crt,
       ROW_NUMBER() OVER(PARTITION BY owner_category ORDER BY owner_category, 
       substr(PROPERTY_ID, 1, 4)) rank
  from owners)
 where rank < 3
   and cat = par_cat

是table吗

+---------+----------+
|  cat    |  kw_crt  |
+---------+----------+
| retired | AAD1     |
| retired | AAH2     |
+---------+----------+

问题是,当我运行这个函数时,我只收到带有“aah2”代码的结果,并且我希望得到kw\u crt列中表示aah2或aad1的所有值。你能帮我换一下功能吗?

xcitsw88

xcitsw881#

您不需要冗余地重复sql查询,也不需要循环。只需要使用bind变量 par_cat 参数(调用 :i_par_cat )在查询字符串中,将符合查询的所有记录放入结果集中。因此,将函数重新创建为:

CREATE OR REPLACE FUNCTION f_test(par_cat in varchar2) RETURN sys_refcursor is
  l_str varchar2(1000);
  l_rc  sys_refcursor;
BEGIN
    l_str := 'SELECT cat, kw_crt
                FROM (SELECT owner_category cat,
                             SUBSTR(property_id, 1, 4) kw_crt,
                             ROW_NUMBER() OVER 
                            (PARTITION BY owner_category 
                             ORDER BY owner_category, SUBSTR(property_id, 1, 4)) rank
                        FROM owners)
                 WHERE rank < 3
                   AND cat = :i_par_cat';

  OPEN l_rc FOR l_str USING par_cat;
  RETURN l_rc;
END;
/
62lalag4

62lalag42#

您正在做大量的工作,通过循环游标来构建动态查询。实际上,您根本不需要动态sql(executeimmediate)。只有当您不知道db对象(表、列等)的名称时,才需要动态sql。在这种情况下,所有已知的;唯一未知的是参数的值。所以

create or replace 
function f_test(p_par_cat in varchar2) 
  return sys_refcursor 
is
  l_rc  sys_refcursor;
begin
  open l_rc for 
       select cat, kw_crt
         from ( select owner_category cat 
                     , substr(property_id, 1, 4) kw_crt 
                     , row_number()
                            over (partition by owner_category 
                                      order by owner_category, substr(property_id, 1, 4)
                                 ) rank
                 from owners
              )
        where rank < 3
          and cat = p_par_cat;
  return l_rc;
end f_test;

-- test
declare 
   rcursor sys_refcursor;
   cat     owners.owner_category%type;
   kw_crt  owners.property_id%type;
begin
   rcursor := f_test('retired');
   dbms_output.put_line('cat' || chr(09)|| chr(09) || 'kw_crt'); 
   loop
      fetch rcursor 
       into cat, kw_crt;
      exit when rcursor%notfound;
     -- dbms_output.put_line('cat: ' || cat || '  kw_crt: ' || kw_crt);
     dbms_output.put_line(cat || chr(09) || kw_crt);     
   end loop;
end;

您还声明在输出中只得到预期行中的一行。这需要您发布调用例程,但您没有这样做。如果你还需要进一步的帮助,就把它贴出来。

相关问题