Oracle 过程或函数返回多个值

Posted

技术标签:

【中文标题】Oracle 过程或函数返回多个值【英文标题】:Oracle procedure or function to return multiple values 【发布时间】:2015-12-31 19:49:47 【问题描述】:

我需要编写一个过程或函数来返回满足以下条件的状态、年龄和类型的计数

select * from ABC
where ABC_id = 2001
and ABC_LEVEL_ID = 1 --status
and ABC_REQUEST_DATE < sysdate --age
and ABC_TYPE_ID = 5; --type

If ABC_ID = 2001 and ABC_LEVEL_ID = 1 
THEN return COUNT(STATUS)


If ABC_ID = 2001 and ABC_REQUEST_DATE < SYSDATE 
THEN return COUNT(AGE)


If ABC_ID = 2001 and ABC_TYPE_ID = 5
THEN return COUNT(TYPE)

所有三个值都应该是传递给前端应用程序的 OUT 参数。

【问题讨论】:

我不确定我是否理解您要执行的操作。为什么在查询中有谓词,然后在“if”语句中重新测试相同的条件?根据定义,返回的任何行都将满足所有这些条件。 【参考方案1】:

您可以在查询中使用CASE 表达式来包含这些约束,例如

select *,
case when ABC_ID = 2001 and ABC_LEVEL_ID = 1  then COUNT(STATUS) else null end as testcol1,
case when ABC_ID = 2001 and ABC_REQUEST_DATE < SYSDATE  then COUNT(AGE) else null end as testcol2,
case when ABC_ID = 2001 and ABC_TYPE_ID = 5  then COUNT(TYPE) else null end as testcol3
from ABC
where ABC_id = 2001
and ABC_LEVEL_ID = 1 --status
and ABC_REQUEST_DATE < sysdate --age
and ABC_TYPE_ID = 5; --type

每条评论:修改后的查询(包括@jeffrykemps 之前的编辑)

select *,
case when ABC_LEVEL_ID = 1  then COUNT(STATUS) end as testcol1,
case when ABC_REQUEST_DATE < SYSDATE  then COUNT(AGE) end as testcol2,
case when ABC_TYPE_ID = 5  then COUNT(TYPE) end as testcol3
from ABC
where ABC_id = 2001
and ABC_LEVEL_ID = 1 --status
and ABC_REQUEST_DATE < sysdate --age
and ABC_TYPE_ID = 5; --type

【讨论】:

合理的解决方案 - 但正如所写,CASE 表达式中的条件与谓词中的条件是多余的,因此您总是会得到 3 个相同的计数,这似乎不太可能是期望的结果. @DaveCosta,是的,你知道 Jeffry 已经编辑了我的答案以包含它,所以我没有碰它,但现在我看到我的答案处于原始状态。【参考方案2】:

我认为如果您的 WHERE 子句使用 OR 操作而不是 AND 操作会更有意义。使用 CASE 语句很容易在查询的投影中进行计数。

由于代码属于存储过程,因此您需要选择某些内容。在这里,我假设直接分配给 OUT 参数。但是,如果您的代码包含其他要求,则应改为填充局部变量,并在过程结束时将它们分配给 OUT 参数。

create or replace procedure get_counts
     ( p_out_status_count out pls_integer
         , p_out_age_count out pls_integer
         , p_out_type_count out pls_integer
as
begin
    select 
        count (case ABC_LEVEL_ID = 1  then 1 else null end),
        count (case ABC_REQUEST_DATE < SYSDATE  then 1 else null end),
        count (case ABC_TYPE_ID = 5  then 1 else null end)
    into p_out_status_count
         , p_out_age_count
         , p_out_type_count
    from ABC
    where ABC_id = 2001
    and (ABC_LEVEL_ID = 1 --status
        or  ABC_REQUEST_DATE < sysdate --age
        or  ABC_TYPE_ID = 5); -- type
end get_counts;

您还可能想要参数化 ABC_ID。在这种情况下,过程的签名可能是:

create or replace procedure get_counts
     ( p_abc_id in abc.abc_id%type   
         , p_out_status_count out pls_integer
         , p_out_age_count out pls_integer
         , p_out_type_count out pls_integer
     )

WHERE 子句是

    ....
    from ABC
    where ABC_id = p_abc_id
    ....

【讨论】:

以上是关于Oracle 过程或函数返回多个值的主要内容,如果未能解决你的问题,请参考以下文章

java中如何获取oracle存储过程返回的多个值。

oracle函数和存储过程有什么区别

ORACLE存储过程里可以声明过程和函数吗

ORACLE 创建的函数 可以返回两个值吗,该怎么做?

oracle面试题

oracle对象之存储函数