循环的条件执行
Conditional execution of loop
我有以下plsql块
for holder in (
select pm.product_holder
, cast(
collect(
product_table(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
test_proc(
holder.product_holder,
holder.product_cats_nos
);
end loop;
在上面sql中,如果任何一列为空,我不想执行循环,它应该终止执行。
列是 product_holder,product_cats_nos
我怎样才能做到这一点?
你应该可以这样做:
loop
if holder.product_holder is null or
holder.product_cats_nos is null
then
exit;
end if;
test_proc(
holder.product_holder,
holder.product_cats_nos
);
end loop;
退出将打破循环。
有关更多信息,请查看文档:http://docs.oracle.com/cd/B19306_01/appdev.102/b14261/exit_statement.htm
另一种方法是使您的 test_proc 程序成为无效证明,但话又说回来,我真的不知道您想做什么 ;)
PRODUCT_NO 似乎是 PRODUCT_MASTER 上的列,而 PRODUCT_CAT_NOS 是查询生成的对象。鉴于此,似乎要测试这两个 columns/objects 的 NULL 状态,您需要在 WHERE 子句中测试第一个,在 HAVING 子句中测试第二个:
for holder in (
select pm.product_holder
, cast(
collect(
product_table(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
WHERE pm.PRODUCT_HOLDER IS NOT NULL -- Added
group by pm.product_holder
HAVING PRODUCT_CAT_NOS IS NOT NULL -- Added
order by pm.product_holder
) loop
test_proc(
holder.product_holder,
holder.product_cats_nos
);
end loop;
不过,总的来说,我认为在循环内使用 IF 语句更清楚 - 但您可以选择更喜欢哪种方法。
分享和享受。
product_cats_nos不能为null(可以包含null,也可以为空,但这是不同的概念:collection在collect聚合函数第一步初始化时不为null)并且您只能让最后 one(您正在按该字段分组)出现 pm.product_holder (因为当您使用 order by 时,空值是最后一个默认值)到为空。
鉴于此,您可以简单地修改查询,添加一个 where 子句
product_holder 不为空。
我有以下plsql块
for holder in (
select pm.product_holder
, cast(
collect(
product_table(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
test_proc(
holder.product_holder,
holder.product_cats_nos
);
end loop;
在上面sql中,如果任何一列为空,我不想执行循环,它应该终止执行。
列是 product_holder,product_cats_nos
我怎样才能做到这一点?
你应该可以这样做:
loop
if holder.product_holder is null or
holder.product_cats_nos is null
then
exit;
end if;
test_proc(
holder.product_holder,
holder.product_cats_nos
);
end loop;
退出将打破循环。 有关更多信息,请查看文档:http://docs.oracle.com/cd/B19306_01/appdev.102/b14261/exit_statement.htm
另一种方法是使您的 test_proc 程序成为无效证明,但话又说回来,我真的不知道您想做什么 ;)
PRODUCT_NO 似乎是 PRODUCT_MASTER 上的列,而 PRODUCT_CAT_NOS 是查询生成的对象。鉴于此,似乎要测试这两个 columns/objects 的 NULL 状态,您需要在 WHERE 子句中测试第一个,在 HAVING 子句中测试第二个:
for holder in (
select pm.product_holder
, cast(
collect(
product_table(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
WHERE pm.PRODUCT_HOLDER IS NOT NULL -- Added
group by pm.product_holder
HAVING PRODUCT_CAT_NOS IS NOT NULL -- Added
order by pm.product_holder
) loop
test_proc(
holder.product_holder,
holder.product_cats_nos
);
end loop;
不过,总的来说,我认为在循环内使用 IF 语句更清楚 - 但您可以选择更喜欢哪种方法。
分享和享受。
product_cats_nos不能为null(可以包含null,也可以为空,但这是不同的概念:collection在collect聚合函数第一步初始化时不为null)并且您只能让最后 one(您正在按该字段分组)出现 pm.product_holder (因为当您使用 order by 时,空值是最后一个默认值)到为空。 鉴于此,您可以简单地修改查询,添加一个 where 子句 product_holder 不为空。