pl/sql 选择变量

pl/sql selecting variables

我有一个简单的 SQL 服务器存储过程

CREATE PROCEDURE [dbo].[some_proc]
AS
BEGIN
    DECLARE @CountA INT
    DECLARE @CountB INT
    DECLARE @CountC INT
    DECLARE @CountD INT
    SELECT @CountA = COUNT(*) FROM some_table WHERE Status IN (7,8,9) 
    SELECT @CountB =  COUNT(*)  FROM some_table WHERE Status IN (5)
    SELECT @CountC = COUNT(*) FROM some_table WHERE Status IN (6) 
    SELECT @CountD = COUNT(*) FROM some_table 


    SELECT @CountA AS aCount , @CountB AS bCount , @CountC AS cCount , @CountD AS dCount

END

GO

我们的产品同时支持 SQL 服务器和 Oracle 数据库,因此我需要将其转换为 PL/SQL 函数。等效的 pl/sql 函数是什么?

预期结果应该是一行数据,列名为 aCount、bCount、cCount、dCount(我已经完成 ADO.net 代码并使用 SQL 服务器存储过程)。这是我到目前为止所拥有的。根据我有限的知识,我知道我需要以某种方式使用光标,但无法弄清楚如何。

CREATE OR REPLACE FUNCTION some_proc(
    p_ix_sys_error OUT number
)
IS

    DECLARE 
        CountA NUMBER;
        CountB NUMBER;
        CountC NUMBER;
        CountD NUMBER;
    BEGIN
        SELECT COUNT(*) INTO CountA FROM some_table WHERE Status IN (7,8,9); 
        SELECT COUNT(*) INTO CountB FROM some_table WHERE Status IN (5);
        SELECT COUNT(*) INTO CountC FROM some_table WHERE Status IN (6);
        SELECT COUNT(*) INTO  CountD FROM some_table; 


    SELECT CountA AS aCount , CountB AS bCount , CountC AS cCount , CountD AS dCount

END

GO

最直接的翻译应该是

CREATE OR REPLACE FUNCTION some_proc(
    p_ix_sys_error OUT number,
    p_rc           OUT sys_refcursor
)
IS
    CountA NUMBER;
    CountB NUMBER;
    CountC NUMBER;
    CountD NUMBER;
BEGIN
    SELECT COUNT(*) INTO CountA FROM some_table WHERE Status IN (7,8,9); 
    SELECT COUNT(*) INTO CountB FROM some_table WHERE Status IN (5);
    SELECT COUNT(*) INTO CountC FROM some_table WHERE Status IN (6);
    SELECT COUNT(*) INTO  CountD FROM some_table; 

    OPEN p_rc
     FOR SELECT CountA AS aCount , 
                CountB AS bCount , 
                CountC AS cCount , 
                CountD AS dCount
           FROM dual;
END;

在任一系统上,针对 table 执行单个查询比 4 个单独的查询

效率更高
CREATE OR REPLACE FUNCTION some_proc(
    p_ix_sys_error OUT number,
    p_rc           OUT sys_refcursor
)
IS
BEGIN
  OPEN p_rc
   FOR SELECT SUM( CASE WHEN Status IN (7,8,9)
                        THEN 1
                        ELSE 0
                    END ) aCount ,
              SUM( CASE WHEN Status IN (5)
                        THEN 1
                        ELSE 0
                    END ) bCount ,
              SUM( CASE WHEN Status IN (6)
                        THEN 1
                        ELSE 0
                    END ) cCount ,
              COUNT(*) dCount 
         FROM some_table;
END;

如果您只需要支持 Oracle 12.1 及更高版本,您可以打开一个隐式结果集而不是声明一个单独的 OUT 参数,但我假设您也想支持更早的版本。