我想创建一个返回多个varchar2列的函数。他是我到目前为止所做的,但在execute immediate
电话中出错了。
FUNCTION FNC_LST_OUR(p_com_code varchar2,
p_from varchar2,
p_to varchar2
) return VARCHAR2 is
v_sql VARCHAR2(30000) := '';
v_sql2 VARCHAR2(30000) := '';
error_msg_tmp varchar2(255);
begin
v_sql := 'select s.com_code, s.p_code, count(*) as Num_SIMRP
from p_stest s
where s.com_code = ''' || p_com_code || '''
and s.s_status = ''ACTIVE''
and s.s_type like ''H%'' ';
if p_from is not null then
v_sql := v_sql || ' and s.p_code between ''' || p_from || ''' and ''' || p_to || '''';
end if;
v_sql := v_sql || ' group by s.com_code,s.p_code
having count(s.p_code)> 0 ';
EXECUTE IMMEDIATE v_sql INTO v_sql2 USING p_com_code; --> Error This Line
return v_sql2;
end;
我需要它来返回多个列,如:
com_code | p_code | num_simrp
A | ADSWQ | 14
A | AQWSA | 8
A | DEWSQ | 10
A | SDERS | 45
A | DFDEW | 80
我必须在包中创建函数,并将结果内部连接作为查询的一部分。
答案 0 :(得分:1)
此代码抛出的错误是" ORA-01006:绑定变量不存在",因为您的execute immediate
有using
子句但查询使用的是连接值而不是绑定变量。当然,使用绑定会更好;通过有条件地更改查询,您会使事情变得复杂。但是如果没有它,它仍然会出错,因为你试图在一个字符串中选择三个值,而这些字符串是不会的。
如果要在另一个查询中使用this的结果,则需要返回一个集合,并且(从内部联接引用)它需要是一个SQL模式级集合类型而不是PL / SQL集合类型
create type fnc_list_obj as object (
com_code varchar2(10),
p_code varchar2(10),
num_simrp number)
/
create type fnc_list_tab as table of fnc_list_obj
/
create package p42 as
function FNC_LST_OUR(P_COM_CODE varchar2,
p_from varchar2,
p_to varchar2
) return fnc_list_tab;
end p42;
/
您不需要使用动态SQL。您可以检查p_from
是否为null并确定要运行哪个完整的SQL查询,或者更简单地在单个查询中包含该检查:
create package body p42 as
function fnc_lst_our(p_com_code varchar2,
p_from varchar2,
p_to varchar2
) return fnc_list_tab is
v_fnc_list fnc_list_tab;
begin
select fnc_list_obj(s.com_code, s.p_code, count(*))
bulk collect into v_fnc_list
from p_stest s
where s.com_code = p_com_code
and s.s_status = 'ACTIVE'
and s.s_type like 'H%'
and (p_from is null or s.p_code between p_from and p_to)
group by s.com_code,s.p_code
having count(s.p_code)> 0;
return v_fnc_list;
end;
end p42;
/
having
子句可能是多余的,但目前它排除了所有p_code
值为空的行,这可能是一种更明显的方法来检查这是否是强度
您可以通过直接调用它来查看找到的内容:
select * from table(p42.fnc_lst_our('A', null, null));
..并且可以使用带有表别名的相同表集合表达式来连接到其他表。
取决于您可能希望使其成为流水线函数的数据量。将逻辑和该表作为内联视图或CTE包含在更大的查询中可能更简单,更有效。
答案 1 :(得分:0)
忘记整个函数,你可以使用子查询。我想你想要这样的东西:
select *
from a_table a
join (select s.com_code, s.p_code, count(*) as Num_SIMRP
from p_stest s
where s.s_status = 'ACTIVE'
and s.s_type like 'H%'
group by s.com_code,s.p_code
having count(s.p_code) > 0) b on b.com_code = a.com_code
and (p_from is null or s.p_code between p_from and p_to)
答案 2 :(得分:0)
create or replace type test_type as object(t_owner varchar2(2000),t_originator varchar2(2000),
t_modify_dat timestamp,t_create_date timestamp);
create or replace type test_table is table of test_type;
create or replace function test_fn(table_name varchar2)
return test_table
as
test_var test_table:=test_table();
t_owner varchar2(2000);
t_originator varchar2(2000);
t_modify_date timestamp;
t_create_date timestamp;
begin
execute immediate 'select "OWNER","ORIGINATOR","MODIFIED","ORIGINATED" from '|| table_name ||'
where revision = 1 and "TYPE" like ''gecPowder'' and "NAME" like ''GE2009-0653'''
into t_owner,t_originator,t_modify_date,t_create_date;
test_var.extend();
--DBMS_OUTPUT.PUT_line(t_owner||t_originator||t_modify_date||t_create_date);
select test_type(t_owner,t_originator,t_modify_date,t_create_date) bulk collect into test_var from dual;
return test_var;
end;