我从查询得到以下结果,我是一个plsql块,我在其中循环记录和send_email给客户.

匿名阻止
FOR i IN (SELECT product_no, product_holder,product_catalogue FROM
product_master)
LOOP
mail_send('PRODMASTER',i.product_holder, i.product_no,i.product_catalogue);
END LOOP;
Run Code Online (Sandbox Code Playgroud)
我想知道什么是最好的方法,如果product_holder在查询结果中重复,而不是发送多封电子邮件,想发送一封包含相关细节的电子邮件.例如,在上述情况下SMITH重复两次,所以用上面的方法将史密斯拿到两封电子邮件,而不是我想发一封电子邮件SMITH与product_no和product_catalogue
我怎样才能做到这一点?
不要在PL/SQL中为循环执行循环 - 使用SQL为您提供可供使用的数据.
首先,我们使用一些测试数据创建您的表(我猜测数据类型 - 您替换为您自己的数据类型):
create table product_master (
product_no varchar2(10)
, product_holder varchar2(10)
, product_catalogue varchar2(10)
)
/
insert into product_master values ('1', 'SMITH', 'TEMP')
/
insert into product_master values ('2', 'SMITH', 'TEMP')
/
insert into product_master values ('3', 'HARRY', 'ARCH')
/
insert into product_master values ('4', 'TOM' , 'DEPL')
/
commit
/
Run Code Online (Sandbox Code Playgroud)
我们想要发送给mail_send每个过程的product_holder是一个包含product_no和的集合(数组)product_catalogue.首先是一个包含这两个元素的类型:
create type t_prod_cat_no as object (
product_no varchar2(10)
, product_catalogue varchar2(10)
)
/
Run Code Online (Sandbox Code Playgroud)
然后是该类型的嵌套表类型(集合类型):
create type t_prod_cat_no_table as
table of t_prod_cat_no
/
Run Code Online (Sandbox Code Playgroud)
然后程序mail_send应该接受product_holder和集合类型:
create or replace procedure mail_send (
p_parameter in varchar2
, p_product_holder in varchar2
, p_product_cats_nos in t_prod_cat_no_table
)
is
begin
dbms_output.put_line('-- BEGIN '||p_parameter||' --');
dbms_output.put_line('Dear '||p_product_holder);
dbms_output.put_line('Your products are:');
for i in 1..p_product_cats_nos.count loop
dbms_output.put_line(
'Catalogue: '||p_product_cats_nos(i).product_catalogue||
' - No: '||p_product_cats_nos(i).product_no
);
end loop;
end mail_send;
/
Run Code Online (Sandbox Code Playgroud)
(我只是使用dbms_output来模拟构建邮件.)
然后你可以在SQL中做一个group by product_holder让SQL生成包含数据的集合:
begin
for holder in (
select pm.product_holder
, cast(
collect(
t_prod_cat_no(pm.product_no,pm.product_catalogue)
order by pm.product_catalogue
, pm.product_no
) as t_prod_cat_no_table
) product_cats_nos
from product_master pm
group by pm.product_holder
order by pm.product_holder
) loop
mail_send(
'PRODMASTER'
, holder.product_holder
, holder.product_cats_nos
);
end loop;
end;
/
Run Code Online (Sandbox Code Playgroud)
上述块的输出将是:
-- BEGIN PRODMASTER --
Dear HARRY
Your products are:
Catalogue: ARCH - No: 3
-- BEGIN PRODMASTER --
Dear SMITH
Your products are:
Catalogue: TEMP - No: 1
Catalogue: TEMP - No: 2
-- BEGIN PRODMASTER --
Dear TOM
Your products are:
Catalogue: DEPL - No: 4
Run Code Online (Sandbox Code Playgroud)
使用SQL在SQL中执行它可以在GROUP BY从PL/SQL到SQL的单个调用中为您提供所有内容,这比第一次调用获得不同的product_holder循环,循环覆盖它更加高效,然后一次调用product_holder以获得每个持有人的产品.
更新:
添加order by到collect上面代码中的函数,以显示您可以控制在集合中填充数据的顺序.
| 归档时间: |
|
| 查看次数: |
69 次 |
| 最近记录: |