Oracle View com Union All e valores com bind

15/10/2019

0

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

Responder

Que tal ter acesso a um e-book gratuito que vai te ajudar muito nesse momento decisivo?

Ver ebook

Recomendado pra quem ainda não iniciou o estudos.

Eu quero
Ver ebook

Recomendado para quem está passando por dificuldades nessa etapa inicial

Eu quero

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar