【问题标题】:Oracle SQL stored procedure with three select statements具有三个选择语句的 Oracle SQL 存储过程
【发布时间】:2015-09-29 17:13:18
【问题描述】:

我正在将当前设置为通过 JAVA 运行的 Oracle SQL 查询转换为存储过程。基本上,同一个表中有三个带有日期范围参数的选择语句。

CREATE OR REPLACE PROCEDURE get_users(startdate_in IN DATE,
                                      enddate_in   IN DATE)
IS
 BEGIN

    DELETE FROM temp_table;

    INSERT INTO temp_table (id, role, date_used, count_s)
      SELECT
        EMPLOYEE.CUSTOMERID                    AS user_id,
        'Customer'                             AS role_,
        to_char(EMPLOYEE.STARTEDON, 'MM-YYYY') AS req_month,
        count(EMPLOYEE.SUBJECT)                AS subj_count
      FROM RCUSER.EMPLOYEE EMPLOYEE
      WHERE EMPLOYEE.STATEID NOT IN (4, 9, 16, 31, 36)
            AND (EMPLOYEE.AGENTID = 0)
            AND (EMPLOYEE.STARTEDON >= to_date(startdate_in, 'yyyy-mm-dd'))
            AND (EMPLOYEE.STARTEDON < to_date(enddate_in, 'yyyy-mm-dd'))
      GROUP BY CUSTOMERID, to_char(EMPLOYEE.STARTEDON, 'MM-YYYY')

      UNION

      SELECT
        EMPLOYEE.PERFORMERID                   AS user_id,
        'Performer'                            AS role_,
        to_char(EMPLOYEE.STARTEDON, 'MM-YYYY') AS req_month,
        count(EMPLOYEE.SUBJECT)                AS subj_count
      FROM RCUSER.EMPLOYEE EMPLOYEE
      WHERE EMPLOYEE.PEID IN (1, 4, 6)
            AND EMPLOYEE.STATEID NOT IN (4, 9, 16, 31, 36)
            AND (EMPLOYEE.AGENTID = 0)
            AND (EMPLOYEE.STARTEDON >= to_date(startdate_in, 'yyyy-mm-dd'))
            AND (EMPLOYEE.STARTEDON < to_date(enddate_in, 'yyyy-mm-dd'))
      GROUP BY PERFORMERID, to_char(EMPLOYEE.STARTEDON, 'MM-YYYY')

      UNION

      SELECT
        employee.performerid                   AS user_id,
        'Approver'                             AS role_,
        to_char(EMPLOYEE.STARTEDON, 'MM-YYYY') AS req_month,
        count(EMPLOYEE.SUBJECT)                AS subj_count
      FROM RCUSER.EMPLOYEE EMPLOYEE
      WHERE EMPLOYEE.PEID IN (2, 3)
            AND EMPLOYEE.STATEID NOT IN (4, 9, 16, 31, 36)
            AND (EMPLOYEE.AGENTID = 0)
            AND (EMPLOYEE.STARTEDON >= to_date(startdate_in, 'yyyy-mm-dd'))
            AND (EMPLOYEE.STARTEDON < to_date(enddate_in, 'yyyy-mm-dd'))
      GROUP BY PERFORMERID, to_char(EMPLOYEE.STARTEDON, 'MM-YYYY');

  END;

运行时,不会将任何内容写入TEMP_TABLE。但是当我对日期范围进行硬编码时,我会得到一些数据。

【问题讨论】:

    标签: sql oracle stored-procedures plsql union


    【解决方案1】:
    CREATE OR REPLACE PROCEDURE GET_PEOPLE(startdate_in IN DATE, enddate_in IN DATE)
    IS
    
    BEGIN
    INSERT INTO temp_table
    (ID, COL1, COL2, ROLE_,START_DATE,END_DATE)
    VALUES
    (select * from
    (Select col1, col2, 'Customer' as Role_, col3, col3
    where col1 in (1,2)
    UNION
    Select col1, col2, 'Authore' as Role_, col3, col3
    where col1 in (3,4)
    UNION
    Select col1, col2,  'Buyer' as Role_,col3, col3
    where col1 in (5,6))
    where col3 between STARTDATE_IN and ENDDATE_IN;
    
    END;
    

    当然,编写好的代码还有很多事情要做:

    • 添加断言 startdate_in 和 enddate_in 是有效日期并且在预期值范围内
    • 而不是临时表,而是返回一个 sys refcursor,其中包含用于在应用程序中处理的结果
    • 使用全局临时表减少撤消日志

    【讨论】:

    • 我使用了你的建议,如果我必须对日期范围进行硬编码,它就可以工作。但是当我将日期作为变量传递时,它返回为空。我在 where 子句部分使用了 "date >= mystoreprocedure.startdate_in 和 date
    • 您不需要在过程中限定参数。 STARTDATE_IN 就足够了。
    • 那么您需要提供一个示例,说明您如何调用过程和输出
    • 我已经用正在使用的实际 SQL 更新了我的原始 SQL。我通过 Oracle SQL 开发人员运行这个存储过程。
    【解决方案2】:

    您可以使用以下形式的单个 SQL 语句来提高效率:

    Select col1,
           col2,
           case
             when col1 in (1,2) then 'Customer'
             when col1 in (3,4) then 'Authore'
             when col1 in (5,6) then 'Buyer'
           end as Role_,
           col3(@startDate),
           col3(@endDate)
    where col1 in (1,2,3,4,5,6);
    

    如果您需要将其写入临时表,则只需将其插入...

    create or replace procedure my_procedure(start_date date, end_date date)
    is
    begin 
    insert into temp_table (... column names ...)
    Select col1,
           col2,
           case
             when col1 in (1,2) then 'Customer'
             when col1 in (3,4) then 'Authore'
             when col1 in (5,6) then 'Buyer'
           end as Role_,
           col3(my_procedure.start_date),
           col3(my_procedure.end_date)
    where col1 in (1,2,3,4,5,6);
    end;
    /
    

    虽然不知道你所说的 col3(@startDate) 是什么意思......也许......

    create or replace procedure my_procedure(start_date date, end_date date)
    is
    begin 
    insert into temp_table (... column names ...)
    Select col1,
           col2,
           case
             when col1 in (1,2) then 'Customer'
             when col1 in (3,4) then 'Authore'
             when col1 in (5,6) then 'Buyer'
           end as Role_,
           my_procedure.start_date,
           my_procedure.end_date
    where col1 in (1,2,3,4,5,6);
    end;
    /
    

    【讨论】:

      猜你喜欢
      • 2023-04-09
      • 1970-01-01
      • 2013-05-12
      • 2014-03-04
      • 1970-01-01
      • 2011-01-07
      • 1970-01-01
      • 2011-12-22
      • 2018-06-27
      相关资源
      最近更新 更多