Что ж, я всегда нахожу код, который использует переменные связывания, а не конкатенацию значений, легче для чтения (и это гораздо лучшая практика). Вы не говорите, как будет выполняться SQL, но предполагая, что REF CURSOR вы можете сделать это так:
vSQL := ' SELECT loc.RMV_REMI_VIRTUALE_COD, loc.LOC_DATA_VER_FIN FROM ENI_SAG_TSF_LOCALITA_DEF loc WHERE 1=1 ';
IF P_LOC_LOCALITA_COD IS NOT NULL THEN
vSQL := vSQL||' AND LOC.LOC_LOCALITA_COD = :P_LOC_LOCALITA_COD ';
ELSE
vSQL := vSQL||' AND (1=1 OR :P_LOC_LOCALITA_COD IS NULL)';
END IF;
IF P_ISTAT_CITTA IS NOT NULL THEN
vSQL := vSQL||' AND loc.COMB_ISTAT_COD = :P_ISTAT_CITTA ';
ELSE
vSQL := vSQL||' AND (1=1 OR :P_ISTAT_CITTA IS NULL)';
END IF;
IF P_PLAY_PLAYER_COD IS NOT NULL THEN
vSQL := vSQL||' AND LOC.PLAY_PLAYER_COD = :P_PLAY_PLAYER_COD ';
ELSE
vSQL := vSQL||' AND (1=1 OR :P_PLAY_PLAYER_COD IS NULL)';
END IF;
IF P_LOC_DATA IS NOT NULL THEN
vSQL := vSQL||' AND TO_TIMESTAMP (:P_LOC_DATA, ''DD/MM/YYYY HH24:MI:SS.FF3'') BETWEEN LOC.LOC_DATA_VER_INI AND LOC.LOC_DATA_VER_FIN ';
ELSE
vSQL := vSQL||' AND (1=1 OR :P_LOC_DATA IS NULL)';
END IF;
OPEN refcur FOR vSQL USING P_LOC_LOCALITA_COD, P_ISTAT_CITTA, P_PLAY_PLAYER_COD, P_LOC_DATA;
Я добавил предложения ELSE, потому что для встроенного динамического SQL число переменных связывания в операторе должно быть фиксированным. Если вы используете пакет DBMS_SQL, вам не нужно этого делать.
Что касается избежания IF, вы можете сделать это:
vSQL := ' SELECT loc.RMV_REMI_VIRTUALE_COD, loc.LOC_DATA_VER_FIN FROM ENI_SAG_TSF_LOCALITA_DEF loc WHERE 1=1 ';
|| CASE WHEN P_LOC_LOCALITA_COD IS NOT NULL THEN
' AND LOC.LOC_LOCALITA_COD = :P_LOC_LOCALITA_COD '
ELSE
' AND (1=1 OR :P_LOC_LOCALITA_COD IS NULL)'
END
|| CASE WHEN P_ISTAT_CITTA IS NOT NULL THEN
' AND loc.COMB_ISTAT_COD = :P_ISTAT_CITTA '
ELSE
' AND (1=1 OR :P_ISTAT_CITTA IS NULL)'
END
... etc.
Очевидно, что теперь у вас есть CASE, но, по крайней мере, вы потеряете все vSQL := vSQL ||
битов.
Если вы добавляете много похожих условий, вы можете заключить логику в функцию, например:
vSQL := ' SELECT loc.RMV_REMI_VIRTUALE_COD, loc.LOC_DATA_VER_FIN FROM ENI_SAG_TSF_LOCALITA_DEF loc WHERE 1=1 ';
|| and_condition ('LOC.LOC_LOCALITA_COD', 'BV1', P_LOC_LOCALITA_COD)
|| and_condition ('loc.COMB_ISTAT_COD', 'BV2', P_ISTAT_CITTA)
... etc.
(Конечно, это не работает для условия МЕЖДУ).