遍历循环查找重复的名字
Traverse through loop to find repeated names
我有以下查询结果和一个 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;
我想知道如果 product_holder
在查询结果中重复而不是发送多封电子邮件,我想知道最好的方法是什么,我想发送一封包含相关详细信息的电子邮件。例如。在上面的例子中,SMITH 被重复了两次,所以用上面的方法 SMITH 会收到两封电子邮件,相反我想用 product_no
和 product_catalogue
发送一封电子邮件到 SMITH
我该怎么做?
您可以使用两个循环并为每个产品持有人发送邮件,像这样;
FOR i IN (SELECT distinct product_holder FROM
product_master)
LOOP
v_products := null;
v_catalogs := null;
for product in (SELECT pm.product_no, pm.product_catalogue FROM
product_master pm where pm.product_holder = i.product_holder)
loop
if v_products is null then
v_products := product.product_no;
else
v_products := v_products ||', ' ||product.product_no;
end if;
if v_catalogs is null then
v_catalogs := product.product_catalogue;
else
v_catalogs := v_catalogs ||', ' ||product.product_catalogue;
end if;
end loop;
mail_send('PRODMASTER',i.product_holder, v_products,v_catalogs);
END LOOP;
为此,不要在 PL/SQL 中的循环中进行循环 - 使用 SQL 为您提供可供使用的数据。
首先我们用一些测试数据创建你的table(我猜是数据类型——你用你自己的数据类型替换):
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
/
我们要为每个 product_holder
发送到 mail_send
过程的是一个包含 product_no
和 product_catalogue
的集合(数组)。所以首先是一个包含这两个元素的类型:
create type t_prod_cat_no as object (
product_no varchar2(10)
, product_catalogue varchar2(10)
)
/
然后是那个类型的嵌套table类型(集合类型):
create type t_prod_cat_no_table as
table of t_prod_cat_no
/
程序 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;
/
(我只是用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;
/
上述块的输出将是:
-- 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
在 SQL 中使用 GROUP BY
执行此操作可在一次调用中获得从 PL/SQL 到 SQL 的所有内容,这比第一个更有效调用以获取 product_holder
的不同集合,对其进行循环,然后每个 product_holder
调用一次以获取每个持有人的产品。
更新:
已将 order by
添加到上述代码中的 collect
函数,以表明您可以控制数据在集合中的填充顺序。
我有以下查询结果和一个 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;
我想知道如果 product_holder
在查询结果中重复而不是发送多封电子邮件,我想知道最好的方法是什么,我想发送一封包含相关详细信息的电子邮件。例如。在上面的例子中,SMITH 被重复了两次,所以用上面的方法 SMITH 会收到两封电子邮件,相反我想用 product_no
和 product_catalogue
SMITH
我该怎么做?
您可以使用两个循环并为每个产品持有人发送邮件,像这样;
FOR i IN (SELECT distinct product_holder FROM
product_master)
LOOP
v_products := null;
v_catalogs := null;
for product in (SELECT pm.product_no, pm.product_catalogue FROM
product_master pm where pm.product_holder = i.product_holder)
loop
if v_products is null then
v_products := product.product_no;
else
v_products := v_products ||', ' ||product.product_no;
end if;
if v_catalogs is null then
v_catalogs := product.product_catalogue;
else
v_catalogs := v_catalogs ||', ' ||product.product_catalogue;
end if;
end loop;
mail_send('PRODMASTER',i.product_holder, v_products,v_catalogs);
END LOOP;
为此,不要在 PL/SQL 中的循环中进行循环 - 使用 SQL 为您提供可供使用的数据。
首先我们用一些测试数据创建你的table(我猜是数据类型——你用你自己的数据类型替换):
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
/
我们要为每个 product_holder
发送到 mail_send
过程的是一个包含 product_no
和 product_catalogue
的集合(数组)。所以首先是一个包含这两个元素的类型:
create type t_prod_cat_no as object (
product_no varchar2(10)
, product_catalogue varchar2(10)
)
/
然后是那个类型的嵌套table类型(集合类型):
create type t_prod_cat_no_table as
table of t_prod_cat_no
/
程序 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;
/
(我只是用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;
/
上述块的输出将是:
-- 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
在 SQL 中使用 GROUP BY
执行此操作可在一次调用中获得从 PL/SQL 到 SQL 的所有内容,这比第一个更有效调用以获取 product_holder
的不同集合,对其进行循环,然后每个 product_holder
调用一次以获取每个持有人的产品。
更新:
已将 order by
添加到上述代码中的 collect
函数,以表明您可以控制数据在集合中的填充顺序。