Хранимая процедура в Oracle с РЕГИСТРОМ-КОГДА в предложении WHERE

#oracle #stored-procedures #plsql #case #where-clause

#Oracle #хранимые процедуры #plsql #случай #where-предложение

Вопрос:

Я работаю в Oracle и пытаюсь выполнить хранимую процедуру для получения данных.

Я хочу вставить case when внутри 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. «где я не прав?» вы не можете вставить регистр в предложение where

2. используя if? и если бы мне пришлось сделать это в предложении where, есть ли способ?

3. ни if, вы не можете использовать and , or , подзапросы и т.д. Взгляните на синтаксис select в документации docs.oracle.com/cd/B19306_01/server.102/b14200 /…

Ответ №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 выражения (т. Е. То, что следует THEN или ELSE ) должен быть буквальным значением, а не логическим выражением. То, что я написал выше, является одним из способов реорганизовать вашу логику таким образом, чтобы она работала в Oracle.