1、创建一个对象:
create or replace type sys_col_id as object(id number(38))
2、定义一个数组
create or replace type sys_tbl_ids as table of sys_col_id
3、算出分隔符的长度,用法:splitter_count('1,2,3,4',','),返回的是分隔符的长度
function splitter_count(str in varchar2, delim in char) return int as
val pls_integer;
begin
val := length(replace(str, delim, delim || ' '));
return val - length(str);
end;
4、根据传入的字符串 返回数组
function tokenize_to_sys_tbl_ids(str varchar2, delim char)
return sys_tbl_ids as
target int;
i int;
this_delim int;
last_delim int;
ids_table sys_tbl_ids := sys_tbl_ids();
BEGIN
i := 1;
last_delim := 0;
target := splitter_count(str, delim);
while i <= target loop
this_delim := instr(str, delim, 1, i);
ids_table.extend();
ids_table(i) := sys_col_id(to_number(substr(str,
last_delim + 1,
this_delim - last_delim - 1)));
i := i + 1;
last_delim := this_delim;
end loop;
ids_table.extend();
ids_table(i) := sys_col_id(to_number(substr(str, last_delim + 1)));
return ids_table;
end;
5、存储过程返回游标
procedure MatchingInvoice(v_Invoiceids varchar2,
v_MatchingIds out sys_refcursor) as
ids_table sys_tbl_ids := sys_tbl_ids();
v_rownum number;
v_sys_tbl_ids sys_tbl_ids;
v_TotalTaxAmount number(19, 6);
v_Totalamount number(19, 6);
begin
v_rownum := 1;
v_TotalTaxAmount := 0;
v_Totalamount := 0;
--把传入的Id放入数组中
v_sys_tbl_ids := pack_cmn.tokenize_to_sys_tbl_ids(v_Invoiceids, ',');
for record_invoice in (Select a.invoiceid,
sum(b.taxamount) taxamount,
a.totalamount / 1.17 * 0.17 newtaxamount
From fi_invoice a
Join fi_invoicedetail b
On a.invoiceid = b.invoiceid
--把数组封装成临时表
Join table(v_sys_tbl_ids) c
On c.id = a.invoiceid
group by a.invoiceid, a.totalamount) loop
--先累加
v_TotalTaxAmount := v_TotalTaxAmount + record_invoice.taxamount;
v_Totalamount := v_Totalamount + record_invoice.newtaxamount;
ids_table.extend();
ids_table(v_rownum) := sys_col_id(record_invoice.invoiceid);
v_rownum := v_rownum + 1;
if abs(round(v_TotalTaxAmount - v_Totalamount, 2)) >= 0.05 then
exit;
end if;
end loop;
open v_MatchingIds for
Select c.id From table(ids_table) c;
end MatchingInvoice;