Sql 从Oracle函数返回多个值

Sql 从Oracle函数返回多个值,sql,oracle,plsql,set-returning-functions,Sql,Oracle,Plsql,Set Returning Functions,我想创建一个函数,将多行返回到对象类型的表中 我已经创建了一个对象和一个嵌套的表对象,现在当我运行这个函数时,出现了一个错误 PL/SQL:SQL语句被忽略 PL/SQL:ORA-00947:值不足 -- Object type creation create or replace type test_object_sn as object ( column_1 varchar2(30), column_2 varchar2(30), column_3 number )

我想创建一个函数,将多行返回到对象类型的表中

我已经创建了一个对象和一个嵌套的表对象,现在当我运行这个函数时,出现了一个错误

PL/SQL:SQL语句被忽略 PL/SQL:ORA-00947:值不足

-- Object type creation
create or replace type test_object_sn as object
(
    column_1 varchar2(30),
    column_2 varchar2(30),
    column_3 number 
);


-- Table of object
create or replace type test_otable_sn as table of test_object_sn; 

-- function (where I get an error)
create or replace function load_test_object_sn
return test_otable_sn
as  
    details test_otable_sn;
begin
    with ad as (select 'a', 'b', 4   from dual
    union all 
    select 'r', '5', 3  from dual
    union all
    select 'g', 's', 3  from dual)
    select * into details from ad; 

    return details;
end;
我想让test\u-otable\u-sn表对象加载数据,然后通过我的load\u-test\u-object\u-sn函数使用table函数查询它 e、 g.从tableload\u test\u object\u序列中选择*

更新: 您知道如何为我有一个sql的场景修改这个吗 包含在要执行的字符串变量中的语句

是的,我们可以使用游标引用SYS_REFCURSOR和OPEN/FETCH/CLOSE,而不是游标和游标FOR循环

语法是开放的。见下文

CREATE OR REPLACE FUNCTION load_test_object_sn
RETURN test_otable_sn
AS  
  details test_otable_sn := test_otable_sn();

  -- Variable stores SQL statement for cursor
  l_sql CLOB :=
    q'[with ad as (
         select 'a' column_1, 'b' column_2, 4 column_3 from dual union all
         select 'r', '5', 3  from dual union all 
         select 'g', 's', 3  from dual
       )
       select *
         from ad]';

  -- Cursor reference allows us to open cursor for SQL statement above
  rc SYS_REFCURSOR;

  -- Define object instance to store each row fetched from the cursor
  l_obj test_object_sn := test_object_sn(NULL, NULL, NULL);

  i PLS_INTEGER := 1;
BEGIN

  -- Explicitly open, fetch from, and close the cursor
  OPEN rc FOR l_sql;
  LOOP
    FETCH rc INTO l_obj.column_1, l_obj.column_2, l_obj.column_3;
    EXIT WHEN rc%NOTFOUND;
    details.extend();
    details(i) := test_object_sn(l_obj.column_1, l_obj.column_2, l_obj.column_3);
    i := i + 1;
  END LOOP;
  CLOSE rc;

  RETURN details;
END;
原始答复: 不幸的是,不能以这种方式将SELECT*INTO用于集合,因此这里有一种填充表的替代方法:

create or replace function load_test_object_sn
return test_otable_sn
as  
    details test_otable_sn := test_otable_sn();
    cursor c_ad is
    with ad as (select 'a' column_1, 'b' column_2, 4 column_3   from dual
    union all 
    select 'r', '5', 3  from dual
    union all
    select 'g', 's', 3  from dual)
    select * from ad;
    i pls_integer := 1;

begin

   for ad_rec in c_ad loop     
      details.extend();
      details(i) := test_object_sn(ad_rec.column_1, ad_rec.column_2, ad_rec.column_3);
      i := i + 1;
   end loop;

    return details;
end;
/
输出:

SQL> SELECT * FROM TABLE(load_test_object_sn);

COLUMN_1   COLUMN_2     COLUMN_3
---------- ---------- ----------
a          b                   4
r          5                   3
g          s                   3

多亏了这一点,您知道如何修改这个场景吗?在这个场景中,我有一个包含在字符串变量中的sql语句要执行?