Oracle中带有CASE-WHEN的WHERE子句中的存储过程

时间:2019-04-03 11:11:17

标签: oracle stored-procedures plsql case where-clause

我正在Oracle中工作,并且正在尝试为GET数据执行存储过程。

我想在WHERE内插入一个大小写,但是它不能编译我,并且以下错误再次出现:

  • 错误(11.5):PL / SQL:忽略了SQL语句
  • 错误(22.37):PL / SQL:ORA-00905:缺少关键字

这是过程:

create or replace PROCEDURE SP_S_DETTAGLIOLOTTI
(
    DATAINIZIO      IN VARCHAR2,
    DATAFINE        IN VARCHAR2,
    CODICEPROFILO   IN NUMBER,
    dett_lotti  OUT SYS_REFCURSOR
)
AS 
BEGIN
    OPEN dett_lotti FOR
    SELECT A.IDLOTTO as IDLOTTO, B.S_DENOMINAZIONE as PROFILOLOTTO, A.TOTRKD as TOTALERECORD,
        CASE WHEN A.DATRPAPSA IS NULL 
             THEN 'NO'  
             ELSE 'SI' 
        END AS ELABORATO  
    FROM DLTOPST A 
    INNER JOIN REQUISITI B 
        ON A.COD_REQUISITO = B.COD_REQUISITI

      WHERE 
        CASE WHEN DATAINIZIO IS NOT NULL AND CODICEPROFILO IS NULL 
             THEN DATA_INVIO_POSTEL BETWEEN TO_DATE(DATAINIZIO, 'DD/MM/YYYY HH24.MI.SS') 
                 AND TO_DATE(DATAFINE, 'DD/MM/YYYY HH24.MI.SS')
             WHEN DATAINIZIO IS NOT NULL AND CODICEPROFILO IS NOT NULL
             THEN DATA_INVIO_POSTEL BETWEEN TO_DATE(DATAINIZIO, 'DD/MM/YYYY HH24.MI.SS') 
                 AND TO_DATE(DATAFINE, 'DD/MM/YYYY HH24.MI.SS') AND COD_REQUISITO = CODICEPROFILO
             ELSE COD_REQUISITO = CODICEPROFILO
        END ;

END SP_S_DETTAGLIOLOTTI;

我在哪里错了?

1 个答案:

答案 0 :(得分:1)

您可以将WHERE子句改写为:

WHERE 
    (DATAINIZIO IS NOT NULL AND CODICEPROFILO IS NULL AND
         DATA_INVIO_POSTEL BETWEEN TO_DATE(DATAINIZIO, 'DD/MM/YYYY HH24.MI.SS') AND
                                   TO_DATE(DATAFINE, 'DD/MM/YYYY HH24.MI.SS')) OR
    (DATAINIZIO IS NOT NULL AND CODICEPROFILO IS NOT NULL AND
         DATA_INVIO_POSTEL BETWEEN TO_DATE(DATAINIZIO, 'DD/MM/YYYY HH24.MI.SS') AND
                                   TO_DATE(DATAFINE, 'DD/MM/YYYY HH24.MI.SS') AND
         COD_REQUISITO = CODICEPROFILO) OR
    COD_REQUISITO = CODICEPROFILO

您当前方法的问题是CASE表达式的谓词(即THENELSE之后的谓词)必须是字面值 value 而不是逻辑表达式。我上面写的是一种以一种适用于Oracle的方式重构逻辑的方法。