我有一个包,其中包含一个过程,我需要在其中查询一个ID号列表,它是varchar2,我将不得不多次查询这个列表,我不希望重做查询,理想情况下,我希望在我的包中创建一个函数,它将返回ID号列表,这样我就可以将ID号数组加载到一个变量中,然后在我的整个过程中,把这个变量当作一个表,我一直在疯狂地搜索,但这似乎是不可能的,有什么方法可以做到吗?
注意:我不能在模式级别创建新类型,而且它也不允许我在本地集合类型上这样做。
而且,我更愿意不使用动态SQL;我的过程中的主查询非常庞大,我不想处理这么大的字符串。
我想做这样的事情:
id_number_list array_type := my_function();
select *
from my_table mt
left join table(id_number_list) idl on mt.id_number = idl.column_value;
编辑:谢谢你的帮助! MTO的答案适用于选择语句连接,就像我上面描述的那样。但是,我还需要从列表中删除id_number所在的表。这给了我一个"invalid data type"错误。如何解释这个错误?数据类型应该总是相同的:varchar2(10)。
这里我在包级别创建类型:
type string_list is table of varchar2(10);
然后创建一个函数,返回ID号列表(出于我们的目的,"action"总是c_action_refresh,因此if语句为真):
function get_modified_ids(scope in smallint, action in smallint) return string_list is
modified_ids string_list := string_list();
last_refreshed date;
begin
last_refreshed := get_last_refreshed_date(scope,action);
if action = c_action_refresh then
select id_number
bulk collect into modified_ids
from(
select id_number
from adv.hr_giving cg
join adv.pbi_dates d
on d.DATE_FULL = trunc(cg.processed_date)
where d.RELATIVE_DATE >= last_refreshed
and d.RELATIVE_DATE <= trunc(CURRENT_DATE)
and cg.fiscal_year >= adv.current_fiscal_year - 6
union
select gi.gift_donor_id as id_number
from adv.gift gi
where gi.date_added >= last_refreshed
or gi.date_modified >= last_refreshed
union
select p.pledge_donor_id as id_number
from adv.pledge_rev p
where p.date_added >= last_refreshed
or p.date_modified >= last_refreshed
union
select a.id_number
from adv.affiliation a
where a.date_added >= last_refreshed
or a.date_modified >= last_refreshed
);
end if;
return(modified_ids);
end get_modified_ids;
然后,在我的过程中,我通过调用函数初始化一个变量:
modified_ids string_list := get_modified_ids(scope,action);
然后我尝试在delete语句中使用该列表:
delete from advrpt.pbi_gvg_profile_ag p
where p.id_number in
(select column_value from table(modified_ids));
这将产生错误ORA-00902:无效的数据类型。id_number的类型是varchar2(10)。同样,它在select语句的连接中工作正常。
为什么我会收到这个错误?
2条答案
按热度按时间3npbholx1#
不要在包中使用变量(因为只有一个变量,如果您的过程在短时间内连续调用两次,那么第二组值将覆盖第一组值,如果在处理第一次调用的中途发生这种情况,则可能会导致问题)。
而是创建用户定义的集合类型:
并将集合作为参数传递给过程:
然后使用调用它,例如:
或者创建类型作为包的一部分:
然后创建程序包主体:
MEMBER OF
运算符仅适用于SQL范围中定义的集合,而不适用于PL/SQL范围中本地定义的集合。*然后使用调用它,例如:
fiddle
lyfkaqu12#
在我看来,你似乎拥有了一切。如果没有,这里有一个例子。
功能:
如何使用它?