Oracle View com Union All e valores com bind

SQL

Oracle

Oracle PL SQL

15/10/2019

Bom dia a todos.
Tenho uma query bem longa que faz uso de UNION ALL para as diferentes condições. Acontece que meu gerenciador de relatórios não aceita queries com mais de 4000 caracteres, e alterar o parâmetro max_string_size para Extended no Oracle está fora de cogitação. Dessa forma, gostaria de transformá-la em uma view.
Como a query faz uso de vários contadores, é necessário fazer o agrupamento, e até aí tudo bem, o problema é que na query uso variáveis de data com bind, como por exemplo :dt_inicial e :dt_final, e como sabemos, não é possível passar binded values em views. Porém se adiciono o campo de data como uma coluna da view, não consigo passar os valores e sou obrigado a agrupar por data também, o que faz com que o resultado da query "quebre". Alguém tem alguma sugestão do que poderia ser feito nesse caso?
Segue a query com Union All para os períodos:
SELECT 
    t.usuario, t.periodo, t.capacidademaxima, t.disponiveis, t.usados, t.faltas, t.cancelamentos, t.pa
    FROM (
    SELECT 
        obter_desc_agenda(a.cd_agenda) usuario,
        'P1' periodo,
   count(case when a.ie_status_agenda <> 'C' then 1 else null end) capacidademaxima,
        count(case when nvl(a.nr_seq_motivo_transf,0) not in (30) and a.ie_status_agenda <> 'C' then 1 else null end) disponiveis,
        count(case when a.ie_status_agenda in ('E','L','N') then 1 else null end) usados,
        count(case when a.ie_status_agenda in ('I') then 1 else null end) faltas,
        count(case when a.ie_status_agenda in ('C') then 1 else null end) cancelamentos,
        count(case when nvl(a.nr_seq_motivo_transf,0) in (10) then 1 else null end) pa
    FROM
        agenda a 
    WHERE
        trunc(a.dt_agenda, 'dd') between :dt_inicial and :dt_final 
        AND to_char(a.dt_agenda, 'HH24:MI:SS') between ('07:00:00') and ('08:59:59')
    GROUP BY
        obter_desc_agenda(a.cd_agenda), 'P1'
    UNION ALL
    SELECT 
        obter_desc_agenda(a.cd_agenda) usuario,
        'P2' periodo,
   count(case when a.ie_status_agenda <> 'C' then 1 else null end) capacidademaxima,
        count(case when nvl(a.nr_seq_motivo_transf,0) not in (30) and a.ie_status_agenda <> 'C' then 1 else null end) disponiveis,
        count(case when a.ie_status_agenda in ('E','L','N') then 1 else null end) usados,
        count(case when a.ie_status_agenda in ('I') then 1 else null end) faltas,
        count(case when a.ie_status_agenda in ('C') then 1 else null end) cancelamentos,
        count(case when nvl(a.nr_seq_motivo_transf,0) in (10) then 1 else null end) pa
    FROM
        agenda a 
    WHERE
        trunc(a.dt_agenda, 'dd') between :dt_inicial and :dt_final  
        AND to_char (a.dt_agenda, 'HH24:MI:SS') between ('09:00:00') and ('11:59:59')
    GROUP BY
        obter_desc_agenda(a.cd_agenda), 'P2'
    UNION ALL
    
    SELECT 
        obter_desc_agenda(a.cd_agenda) usuario,
        'P3' periodo,
   count(case when a.ie_status_agenda <> 'C' then 1 else null end) capacidademaxima,
        count(case when nvl(a.nr_seq_motivo_transf,0) not in (30) and a.ie_status_agenda <> 'C' then 1 else null end) disponiveis,
        count(case when a.ie_status_agenda in ('E','L','N') then 1 else null end) usados,
        count(case when a.ie_status_agenda in ('I') then 1 else null end) faltas,
        count(case when a.ie_status_agenda in ('C') then 1 else null end) cancelamentos,
        count(case when nvl(a.nr_seq_motivo_transf,0) in (10) then 1 else null end) pa
    FROM
        agenda a 
    WHERE
        trunc(a.dt_agenda, 'dd') between :dt_inicial and :dt_final  
        and to_char (a.dt_agenda, 'HH24:MI:SS') between ('12:00:00') and ('13:59:59')
    GROUP BY
        obter_desc_agenda(a.cd_agenda), 'P3'
    UNION ALL
    SELECT 
        obter_desc_agenda(a.cd_agenda) usuario,
        'P4' periodo,
         count(case when a.ie_status_agenda <> 'C' then 1 else null end) capacidademaxima,
        count(case when nvl(a.nr_seq_motivo_transf,0) not in (30) and a.ie_status_agenda <> 'C' then 1 else null end) disponiveis,
        count(case when a.ie_status_agenda in ('E','L','N') then 1 else null end) usados,
        count(case when a.ie_status_agenda in ('I') then 1 else null end) faltas,
        count(case when a.ie_status_agenda in ('C') then 1 else null end) cancelamentos,
        count(case when nvl(a.nr_seq_motivo_transf,0) in (10) then 1 else null end) pa
    FROM
        agenda a 
    WHERE
        trunc(a.dt_agenda, 'dd') between :dt_inicial and :dt_final 
         and to_char (a.dt_agenda, 'HH24:MI:SS') between ('14:00:00') and ('17:59:59')
    GROUP BY
        obter_desc_agenda(a.cd_agenda), 'P4'
    UNION ALL
    
    SELECT 
        obter_desc_agenda(a.cd_agenda) usuario,
        'P5' periodo,
        count(case when a.ie_status_agenda <> 'C' then 1 else null end) capacidademaxima,
        count(case when nvl(a.nr_seq_motivo_transf,0) not in (30) and a.ie_status_agenda <> 'C' then 1 else null end) disponiveis,
        count(case when a.ie_status_agenda in ('E','L','N') then 1 else null end) usados,
        count(case when a.ie_status_agenda in ('I') then 1 else null end) faltas,
        count(case when a.ie_status_agenda in ('C') then 1 else null end) cancelamentos,
        count(case when nvl(a.nr_seq_motivo_transf,0) in (10) then 1 else null end) pa
    FROM
        agenda a 
    WHERE
        trunc(a.dt_agenda, 'dd') between :dt_inicial and :dt_final
         and to_char (a.dt_agenda, 'HH24:MI:SS') between ('18:00:00') and ('22:00:00')
    GROUP BY
        obter_desc_agenda(a.cd_agenda), 'P5'
    UNION ALL
    
    SELECT 
        obter_desc_agenda(a.cd_agenda) usuario,
        'Total' periodo, 
        count(case when a.ie_status_agenda <> 'C' then 1 else null end) capacidademaxima,
        count(case when nvl(a.nr_seq_motivo_transf,0) not in (30) and a.ie_status_agenda <> 'C' then 1 else null end) disponiveis,
        count(case when a.ie_status_agenda in ('E','L','N') then 1 else null end) usados,
        count(case when a.ie_status_agenda in ('I') then 1 else null end) faltas,
        count(case when a.ie_status_agenda in ('C') then 1 else null end) cancelamentos,
        count(case when nvl(a.nr_seq_motivo_transf,0) in (10) then 1 else null end) pa
    FROM
        agenda a 
    WHERE
trunc(a.dt_agenda, 'dd') between :dt_inicial and :dt_final 

    GROUP BY
        obter_desc_agenda(a.cd_agenda), 'Total'
) t
order by usuario, periodo;


Alguma sugestão de como transformar essa query em view de forma que eu possa definir os períodos iniciais e finais? Se eu adicionar dt_agenda no select preciso incluí-lo no GROUP BY, o que quebra completamente a query.

Obrigado
Diego

Diego

Curtidas 0
POSTAR