从 PL/SQL 关联数组中的元素获取不同的值
Posted
技术标签:
【中文标题】从 PL/SQL 关联数组中的元素获取不同的值【英文标题】:Get Distinct Value from an Element in a PL/SQL Associative Array 【发布时间】:2017-07-12 20:28:39 【问题描述】:假设我有一张表XX_TABLE_SAMPLE
,记录如下:
TAB_ID BATCH_NAME EMP_NO EMP_NAME STATUS SALARY CATEGORY
------ ---------- ------ -------- -------- ------- ------------
1 BATCH_A 1 Jared Active 1000 (NULL)
2 BATCH_A 2 Siege Active 3000 (NULL)
3 BATCH_A 45 James Suspended 2000 (NULL)
4 BATCH_B 67 Harry Active 100 (NULL)
5 BATCH_B 99 Pikachu Active 10000 (NULL)
6 BATCH_x 100 Eren Suspended 4000 (NULL)
我有如下的 PL/SQL 块(请注意 cmets):
declare
cursor emp_cur is
select *
from XX_TABLE_SAMPLE
where status = 'Active';
type emp_cur_type is table of XX_TABLE_SAMPLE%rowtype index by pls_integer;
emp_rec emp_cur_type;
begin
open emp_cur;
fetch emp_cur
bulk collect
into emp_rec;
close emp_cur;
/* do some pre-processing here via another stored procedure
but the problem is, it has a parameter of p_batch_name, not a type of associative array
for i in emp_rec.first..emp_rec.last loop
pay_pkg.validate_pay (p_batch_name => emp_rec(i).p_batch_name);
end;
-- the problem with this is that it will loop 4 times (twice each for BATCH_A and BATCH_B)
when it should only get the 2 batch names (BATCH_A and BATCH_B)
*/
-- then check the salary of the emp and update the associative array
for i in emp_rec.first..emp_rec.last loop
if emp_rec(i).salary > 200 and emp_rec(i).salary < 3000 then
emp_rec(i).CATEGORY = 'Manager';
end if;
end loop;
forall i in emp_rec.first..emp_rec.last
update XX_TABLE_SAMPLE
set CATEGORY = emp_rec(i).CATEGORY
where TAB_ID = emp_rec(i).TAB_ID;
end;
这样,我想在关联数组中获取元素 Batch_Name
的不同值
然后将其传递给存储过程pay_pkg.validate_pay
。
关于如何在不声明另一个显式光标的情况下实现这一目标的任何想法?
【问题讨论】:
能否请您告诉我们您需要的数组结果是什么? @JuanCarlosOropeza,关联数组将填充“活动”状态的记录(4 行)。但是,在我将调用pay_pkg.validate_pay
的部分中,我只需要从 1 列 (Batch_Name
) 中获取 2 行(“BATCH_A”和“BATCH_B”)
Migs 问题是如果您不提供所需的结果,我没有时间尝试破译您的代码所做的事情。我的建议是简化问题并专注于你不能做的事情。是查询吗? ,是创建一个数组吗?因为我不认为你需要一个光标。
【参考方案1】:
在我看来,您似乎在考虑不必要的复杂解决方案。我认为您的示例可以简化为以下需要零 PL/SQL 数据结构的解决方案(r
是隐式记录类型,但编译器会为您制作!)。
顺便说一句,PL/SQL 中没有必要害怕游标。
declare
-- a dummy placeholder for the "tricky" subprogram
procedure validate_pay(p_batch_name in varchar2) is begin null; end;
begin
for r in (select distinct batch_name
from xx_sample_data
where status = 'Active')
loop
validate_pay(p_batch_name => r.batch_name);
end loop;
update xx_sample_data set
category = 'Manager'
where status = 'Active'
and salary between 201 and 2999
;
end;
/
【讨论】:
只是一个提示,您假设薪水是一个整数以简化> <
条件,但我怀疑情况是否如此。
@JuanCarlosOropeza 是的,你是对的。我把它作为 OP 的练习。【参考方案2】:
也许是你没有说的其他东西,但如果你需要"BATCH_A", "BATCH_B"
为什么不直接使用:
SELECT DISTINCT BATCH_NAME
FROM XX_TABLE_SAMPLE
WHERE status = 'Active'
AND salary > 200
AND salary < 3000
【讨论】:
这就是我要问的情况。是否可以只使用数组子集的不同值,而不必显式声明它们? 我不知道怎么做。你有一套,现在需要另一套。您可以循环第一组并删除重复项,但为此只需从头开始创建一组。创建两个集合有什么问题?【参考方案3】:如果您在 oracle 12 上,还有另一种方法。
但这涉及从关联数组中进行选择
见 Select from PLSQL Associative array?
【讨论】:
以上是关于从 PL/SQL 关联数组中的元素获取不同的值的主要内容,如果未能解决你的问题,请参考以下文章