Concatenar Ano+mês+dia e usar to_Date

Dúvidas, dicas e truques de PL/SQL. Aqui também vão assuntos relacionados a pacotes, triggers, funções, Java-Stored Procedures, etc
Responder
suelana
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 63
Registrado em: Qui, 10 Ago 2006 6:07 pm
Localização: Joinville-SC
Suelana BLU-JLLE

Gostaria de saber se há como montar uma data com 3 campos numa variavel date;

EXEMPLO:

Selecionar tudo

declare
  w_ano number;
  w_mês number;
  w_dia number;
   
  w_data date;
begin
     w_data := To_Date( p_ano||'/'||To_Char(p_mês,'00')||'/'||to_char(p_dia,'00')  ) ;

    dbms_output.put_line('Data: '||w_data);

end;

Este exemplo está OK dentro do SQL tools, mas quando concateno dentro de uma package chamada por um Report, dá erro:

Selecionar tudo

ORA-01861: o literal não corresponde à string de formato
Descobri que o formato de datas é 'dd-mon-yyyy' no report.

Como controlar isto? gostaria de definir o formato da data na hora da criação de w_data para não ter supresas no futuro, se alterarem o perfil de usuário.
thiago_r_f
Rank: Programador Pleno
Rank: Programador Pleno
Mensagens: 43
Registrado em: Qui, 17 Abr 2008 4:02 pm
Localização: Rio de Janeiro - RJ
O Backup é meu pastor e nada me faltará!
Thiago Rodrigues de Farias

Embora seja opcional, não seria melhor colocar a máscara?

Selecionar tudo

w_data := To_Date( p_ano||'/'||To_Char(p_mês,'00')||'/'||to_char(p_dia,'00'), 'yyyy/mm/dd' ) ;
Verifique tb o datatype do campo na tabela!
Abs.
nandosistemas
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 6
Registrado em: Ter, 14 Abr 2009 11:40 am
Localização: BH - MG

Thiago, com a máscara não funciona quando coloco em uma variável. Veja na procedure abaixo a primeira linha do Where.

Selecionar tudo

CREATE OR REPLACE PROCEDURE sp_tempos_elevados (cv_1 IN OUT SYS_REFCURSOR, 
HIERARQUIA IN VARCHAR2, 
mês_ANO IN VARCHAR2 , 
HORAS IN INT, 
ORDENACAO INT) 
IS 

SQUERY VARCHAR(30000); 

BEGIN 

SQUERY:= 
'SELECT h.cod_hierarq AS codLocal, 
Round((i.qtd_cons_ating+i.qtd_cons_rur_ating+i.qtd_cons_prim_atingi)*i.min_duracao,0) AS INDEXADOR, 
i.num_id_interrupcao, 
i.num_documento, 
(f.dat_inicio) AS dat_inicio, 
(i.dat_termino)AS dat_termino, 
Trunc(((i.min_duracao/60)/24),0) AS dia_duracao, 
Trunc(i.min_duracao/60,0) AS hor_duracao, 
Round(i.min_duracao,0) AS min_duracao, 
i.qtd_cons_rur_ating AS ConsRural, 
i.qtd_cons_prim_atingi AS ConsPri, 
i.qtd_cons_ating AS ConsUrbano 

FROM tinter_intertrecho f, titensinter i, thierarquia h, ttransferenciaconint t, 

(SELECT l.COD_LOCAL,s.COD_LOCAL AS super,r.COD_LOCAL AS reg FROM tOrdemHierarquia s 
inner join tOrdemHierarquia r ON (s.COD_LOCAL=r.NUM_ID_PAI) 
inner join tOrdemHierarquia l ON (r.COD_LOCAL=l.NUM_ID_PAI) 
WHERE s.COD_LOCAL=NVL2('|| HIERARQUIA||',(SELECT DISTINCT num_id_hierarquia FROM thierarquia WHERE cod_Hierarq=CAST(' || HIERARQUIA ||' AS INT)),s.COD_LOCAL) 

UNION 

SELECT l.COD_LOCAL,s.COD_LOCAL AS super, r.COD_LOCAL AS reg FROM tOrdemHierarquia s 
inner join tOrdemHierarquia r ON (s.COD_LOCAL=r.NUM_ID_PAI) 
inner join tOrdemHierarquia l ON (r.COD_LOCAL=l.NUM_ID_PAI) 
WHERE r.COD_LOCAL=NVL2('|| HIERARQUIA||',(SELECT DISTINCT num_id_hierarquia FROM thierarquia WHERE cod_Hierarq=CAST('|| HIERARQUIA||' AS INT)),r.COD_LOCAL) 

UNION 

SELECT l.COD_LOCAL, s.COD_LOCAL AS super, r.COD_LOCAL AS reg FROM tOrdemHierarquia s 
inner join tOrdemHierarquia r ON (s.COD_LOCAL=r.NUM_ID_PAI) 
inner join tOrdemHierarquia l ON (r.COD_LOCAL=l.NUM_ID_PAI) 
WHERE l.COD_LOCAL=NVL2('|| HIERARQUIA||',(SELECT DISTINCT num_id_hierarquia FROM thierarquia WHERE cod_Hierarq=CAST('|| HIERARQUIA||' AS INT)),l.COD_LOCAL) 
)l 

WHERE TO_DATE(f.dat_inicio,' || 'mm/yyyy'||') = '||mês_ANO||' 
AND (i.min_duracao-Nvl(t.min_duracao,0)) >' || HORAS || ' * 60 
AND f.num_id_interrupcao = i.num_id_interrupcao 
AND i.num_id_hierarquia = h.num_id_hierarquia 
AND h.num_id_hierarquia = l.cod_local 
AND i.num_id_interrupcao = t.num_id_interrupcao(+) 
AND i.num_id_item = t.num_id_item(+)'; 



OPEN cv_1 FOR SQUERY; 

END; 
/ 
Quando tento executá-la, um erro é retornado, me informando que o identificador 'yyyy' é inválido. Esse identificador é o que está na primeira linha do WHERE.

TO_DATE(f.dat_inicio,' || 'mm/yyyy'||') = '||mês_ANO||'


A questao é: como faço pra concatenar a máscara nesta caso, usando to_date? Já tentei de tudo e não consegui.

Eu preciso da consulta em uma variável, pois esta query será dinâmica e pedaços serão incluídos de acordo com a opção selecionada pelo usuário.

Desde já, obrigado.
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

Você precisa usar mesmo um select dinâmico? Parece que tudo o que você quer ali dá para ser passado por parâmetros num cursor simples ou por bind variable. Por exemplo:

Selecionar tudo

SQL> set serveroutput on;
SQL> declare
  2    cursor c_test(p_num in number) is
  3      with t as (select 1 num, 'AAA' as nome from dual
  4                 union all select 2 num, 'BBB' nome from dual
  5                 union all select 3 num, 'CCC' nome from dual)
  6      select nome
  7        from t
  8       where t.num = p_num;
  9    w_num varchar2(10);
 10  begin
 11    open c_test(3);
 12    fetch c_test
 13      into w_num;
 14    close c_test;
 15    dbms_output.put_line('Selected ' || w_num || '!');
 16  end;
 17  /
Selected CCC!

Procedimento PL/SQL concluído com sucesso.

SQL> 
Você pode passar direto via parâmetro do cursor, o que inclusive torna a execução mais rápida porque o sql é otimizado para ser reutilizado.

Se você optar por usar mesmo o sql dinâmico, sem problemas, mas mude as variáveis lá dentro para bind variables, como no exemplo abaixo:
http://download.oracle.com/docs/cd/B193 ... sthref1135
Você ganha desempenho e ainda previne que sua query seja explorada com sql injection, um dos problemas mais recorrentes de segurança de software que existem.

O problema no to_date é que você está colocando mm/yyyy como se fossem variáveis, e eles são constantes (caractere). Além disso, f.dat_inicio não é uma data? Se for, seu to_date deveria estar no outro lado da igualdade

Selecionar tudo

f.dat_inicio = to_date('|| mês_ANO || ', ''mm/yyyy'')
http://download.oracle.com/docs/cd/B193 ... SQLRF06132
http://download.oracle.com/docs/cd/B193 ... #sthref373

Se pintar dúvidas, manda ver.

Abraço.[/url]
nandosistemas
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 6
Registrado em: Ter, 14 Abr 2009 11:40 am
Localização: BH - MG

Primeiramente obrigado pelas dicas. É bom conversar com quem realmente entende do assunto.

A utilização do Bind Variable vai ajudar bastante aqui. E os outros links eu farei a leitura assim q possível.

Eu realmente preciso de um select dinâmico. O que postei aqui foi apenas um consulta ínfima perto do restante.

Mas o problema inicial eu ainda não sonsegui resolver, que é o problema da máscara. A consulta da postagem anterior funciona perfeitamente quando rodo direto, sem colocar a query em uma variável string.

Colocando a consulta em uma variável eu não consigo de forma nenhuma executar a procedure.

Quando faço a alteração que você propôs:

Selecionar tudo

f.dat_inicio = to_date('|| mês_ANO || ', ''mm/yyyy'') 

é retornada uma mensagem de erro: ORA-01858: a non-numeric character was found where a numeric was expected.

É importante frisar que eu estou executando esta procedure direto de um relatório desenvolvido em Reporting Service. Se eu retiro da consulta o campo mês_ANO e passo uma constante ('01/2009', por exemplo), a execução procede perfeitamente.

As outras variáveis que passo tb funcionam perfeitamente. Só mesmo a data está me dando trabalho.

Alguma sugestão do que possa ser???

Vou tentar executar esta procedure diretamente do sql Plus pra ver se ela roda.


Obrigado mais uma vez.
nandosistemas
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 6
Registrado em: Ter, 14 Abr 2009 11:40 am
Localização: BH - MG

O problema eu encontrei. Como disse, estou usando o Reporting Service pra chamar a procedure. Nele, aau passo a data como string para a procedure. Porém, quando executo a procedure, esta data está sendo tratada como número.

Para ser mais claro:

Eu passei a data '02/2009' no parâmetro mês_ANO. Coloquei este parâmetro no meu select para verificar, e ele me retornou o valor 0,0009955. Percebeu? É exatamente a divisão de 2 por 2009. Ou seja, está tratando a minha string como número. Agora estou tentando fazer um cast ou algo parecido, mas ainda não deu certo.

Sugestões?
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

Falha minha, cara, esqueci um pequeno detalhe :oops:

Selecionar tudo

f.dat_inicio = to_date('''|| mês_ANO || ''', ''mm/yyyy'') 
o mês_ano precisa estar contido entre apóstrofos.
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

Ou então, no exemplo abaixo, usando bind variable em vez de concatenar no sql (bem mais elegante e rápido):

Selecionar tudo

SQL> set serveroutput on;
SQL> declare
  2    c_test sys_refcursor;
  3    p_dat varchar2(8) := '04/2009';
  4    w_num varchar2(10);
  5  begin
  6    open c_test for
  7    'with t as (select 1 num, ''AAA'' as nome from dual
  8                 union all select 2 num, ''BBB'' nome from dual
  9                 union all select 3 num, ''CCC'' nome from dual)
 10      select nome
 11        from t
 12       where t.num = 2
 13       and trunc(sysdate, ''MM'') = to_date(:p_in_data, ''mm/yyyy'')'
 14    using p_dat;
 15    fetch c_test
 16      into w_num;
 17    close c_test;
 18    dbms_output.put_line('Selected ' || w_num || '!');
 19  end;
 20  /
Selected BBB!

Procedimento PL/SQL concluído com sucesso.

SQL> 
nandosistemas
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 6
Registrado em: Ter, 14 Abr 2009 11:40 am
Localização: BH - MG

Cara, muitíssimo obrigado. Funcionou perfeitamente.

Mas já q estamos na discussão, vamos pensar em termo de performance.

As queries que eu tenho aqui são muito grandes. Elas tem várias sub queries envolvidas. Com este exemplo q você me passou, eu consegui isolar a subquery de uma subquery, que se repetia em vários pontos. Acho q só aí já vai melhorar bastante.

Mas dê uma olhada na consulta abaixo. Ela é grande mas é só pra exemplificar a estrutura das queries que eu tenho. Repare que existem várias subqueries para gerar o meu resultado.

Selecionar tudo

SELECT To_Char(aux.dat_inicio,'DD/MM/YYYY')AS dat_inicio, 

        Round( sum((NVL (fecdecProg.valdec,0) - NVL (transfProg.valtrans,0)) / DECODE (cc.pot,NULL,1,0,1,cc.pot)),10) AS Dec_Prog, 

        Round(sum ((NVL (fecdecAcid.valdec,0) - NVL (transfAcid.valtrans,0)) / DECODE (cc.pot,NULL,1,0,1,cc.pot) ),10) AS Dec_Acid, 

        Round ( Sum (((NVL (fecdecProg.valdec,0) - NVL (transfProg.valtrans,0)) / DECODE (cc.pot,NULL,1,0,1,cc.pot) ) + 
              ((NVL (fecdecAcid.valdec,0) - NVL (transfAcid.valtrans,0)) / DECODE (cc.pot,NULL,1,0,1,cc.pot))),10) AS DEC_Total, 

        Round(Sum(((NVL (fecdecAcid.valfec,0) ) / DECODE (cc.pot,NULL,1,0,1,cc.pot))),10) AS Fec_Acid, 

        Round(Sum(((NVL (fecdecProg.valfec,0) ) / DECODE (cc.pot,NULL,1,0,1,cc.pot))),10) AS Fec_Prog, 

        Round(sum(((NVL (fecdecProg.valfec,0) ) / DECODE (cc.pot,NULL,1,0,1,cc.pot)) + 
          ((NVL (fecdecAcid.valfec,0) ) / DECODE (cc.pot,NULL,1,0,1,cc.pot))),10) as Fec_Total, 

        Round(Sum(Nvl(freqProg.fProg,0)),4) AS Frequencia_Programada, 

        Round(Sum(Nvl(freqAcid.fAcid,0)),4) AS Frequencia_Acidental, 

        Round(Sum(Nvl(freqProg.fProg,0)) + Sum(Nvl(freqAcid.fAcid,0)),4)AS Frequencia_total 

 FROM ttipotrecho tr, 
   (  SELECT (SUM (qtd_cons_distr +qtd_cons_prim +qtd_cons_rur) /1) pot, 
             Extract( MONTH FROM dat_refer ) AS mês, 
             extract( YEAR FROM dat_refer ) AS ano 
     FROM  tpotencia p 
     WHERE p.dat_refer >= TRUNC(To_Date(mês_ANO,'MM/YYYY')) 
     AND   p.dat_refer < TRUNC(LAST_DAY(TO_DATE(mês_ANO,'MM/YYYY')),'DD')+1 
     and   p.cod_conj_aneel_2001= COD_ANEEL 
     GROUP BY Extract( MONTH FROM dat_refer ), extract( YEAR FROM dat_refer ) 
   ) cc, 

   (  SELECT DISTINCT t.cod_tipo_trecho, trunc( t.Dat_inicio ) AS Dat_inicio 
      FROM  tinter_intertrecho t 
      WHERE t.num_id_interrupcao IN 
              (  SELECT t.num_id_interrupcao 
                 FROM  titensinter i, tinter_intertrecho t,tpotencia p 
                 WHERE t.num_id_interrupcao = i.num_id_interrupcao 
                 AND   i.num_id_hierarquia=p.num_id_hierarquia 
                 AND   p.cod_conj_aneel_2001= COD_ANEEL 
                 AND   t.dat_inicio >=  TRUNC(TO_DATE(mês_ANO,'MM/YYYY')) 
                 AND   t.dat_inicio < TRUNC(LAST_DAY(TO_DATE(mês_ANO,'MM/YYYY')),'DD')+1 
              ) 
      GROUP BY   t.cod_tipo_trecho, trunc( t.Dat_inicio ) 
   ) aux, 

   (  SELECT Sum((i.qtd_cons_ating + i.qtd_cons_prim_atingi + i.qtd_cons_rur_ating) * NVL (t.num_religam_calculado,1)) valfec, 
             (Sum((i.qtd_cons_ating + i.qtd_cons_prim_atingi + i.qtd_cons_rur_ating) * i.min_duracao) / 60) valdec,t.cod_tipo_trecho, 
             Trunc( t.Dat_inicio ) AS Dat_inicio 
      FROM   tinter_intertrecho t,titensinter i 
      WHERE  t.dat_inicio >=  TRUNC(TO_DATE(mês_ANO,'MM/YYYY')) 
      AND    t.dat_inicio < TRUNC(LAST_DAY(TO_DATE(mês_ANO,'MM/YYYY')),'DD')+1 
      AND    t.num_id_interrupcao =i.num_id_interrupcao 
      AND    i.num_id_hierarquia IN 
                   ( SELECT DISTINCT num_id_hierarquia 
                     FROM tpotencia 
                     WHERE cod_conj_aneel_2001 = COD_ANEEL 
                     AND dat_refer >= TRUNC(To_Date(mês_ANO,'MM/YYYY')) 
                     AND dat_refer < TRUNC(LAST_DAY(TO_DATE(mês_ANO,'MM/YYYY')),'DD')+1 
                   ) 
      AND (NOT(t.num_idt_grupo_causas = 4 AND t.num_idt_causa_interrupcao = 7)) 
      AND (NOT(t.num_idt_grupo_causas = 10)) 
      AND t.dat_inicio >=  TRUNC(TO_DATE(mês_ANO,'MM/YYYY')) 
      AND t.dat_inicio < TRUNC(LAST_DAY(TO_DATE(mês_ANO,'MM/YYYY')),'DD')+1 
      AND t.tag_prog_acid='A' 
      AND i.tag_mom_sus = NVL(TIPO_DURACAO,i.tag_mom_sus) 
      GROUP BY t.cod_tipo_trecho,   Trunc( t.Dat_inicio ) 

   ) fecdecAcid, 

   (  SELECT SUM ((i.qtd_cons_ating +i.qtd_cons_prim_atingi +i.qtd_cons_rur_ating) * 
             NVL (t.num_religam_calculado,1)) valfec, 
             (SUM ((i.qtd_cons_ating + i.qtd_cons_prim_atingi + i.qtd_cons_rur_ating) * i.min_duracao) / 60) valdec, t.cod_tipo_trecho, 
             Trunc( t.Dat_inicio ) AS Dat_inicio 
      FROM tinter_intertrecho t, titensinter i 
      WHERE t.dat_inicio >=  TRUNC(TO_DATE(mês_ANO,'MM/YYYY')) 
      AND t.dat_inicio < TRUNC(LAST_DAY(TO_DATE(mês_ANO,'MM/YYYY')),'DD')+1 
      AND t.num_id_interrupcao =i.num_id_interrupcao 
      AND   i.num_id_hierarquia IN 
                   ( SELECT DISTINCT num_id_hierarquia 
                     FROM tpotencia 
                     WHERE cod_conj_aneel_2001 = COD_ANEEL 
                     AND dat_refer >= TRUNC(To_Date(mês_ANO,'MM/YYYY')) 
                     AND dat_refer < TRUNC(LAST_DAY(TO_DATE(mês_ANO,'MM/YYYY')),'DD')+1 
                   ) 
      AND (NOT(t.num_idt_grupo_causas = 4 AND t.num_idt_causa_interrupcao = 7)) 
      AND (NOT(t.num_idt_grupo_causas = 10)) 
      AND t.dat_inicio >=  TRUNC(TO_DATE(mês_ANO,'MM/YYYY')) 
      AND t.dat_inicio < TRUNC(LAST_DAY(TO_DATE(mês_ANO,'MM/YYYY')),'DD')+1 
      AND t.tag_prog_acid='P' 
      AND i.tag_mom_sus = NVL(TIPO_DURACAO,i.tag_mom_sus) 
      GROUP BY t.cod_tipo_trecho,   Trunc( t.Dat_inicio ) 
   ) fecdecProg, 

   (  SELECT (SUM ((a.qtd_cons_ating + a.qtd_cons_prim_ating + a.qtd_cons_rur_ating) * a.min_duracao ) / 60) valtrans, t.cod_tipo_trecho, 
             Trunc( t.Dat_inicio ) AS Dat_inicio 
      FROM   tinter_intertrecho t, 
             ttransferenciaconint a, 
             titensinter i 

      WHERE t.dat_inicio >=  TRUNC(TO_DATE(mês_ANO,'MM/YYYY')) 
      AND   t.dat_inicio < TRUNC(LAST_DAY(TO_DATE(mês_ANO,'MM/YYYY')),'DD')+1 
      AND   t.num_id_interrupcao =i.num_id_interrupcao 
      AND   i.num_id_interrupcao =a.num_id_interrupcao 
      AND   i.num_id_item =a.num_id_item 
      AND   i.num_id_hierarquia IN 
                   ( SELECT DISTINCT num_id_hierarquia 
                     FROM tpotencia 
                     WHERE cod_conj_aneel_2001 = COD_ANEEL 
                     AND dat_refer >= TRUNC(To_Date(mês_ANO,'MM/YYYY')) 
                     AND dat_refer < TRUNC(LAST_DAY(TO_DATE(mês_ANO,'MM/YYYY')),'DD')+1 
                   ) 
      AND   (NOT(t.num_idt_grupo_causas = 4 AND t.num_idt_causa_interrupcao = 7)) 
      AND   (NOT(t.num_idt_grupo_causas = 10)) 
      AND   t.tag_prog_acid='P' 
      AND t.tag_mom_sus = NVL(TIPO_DURACAO,t.tag_mom_sus) 
      GROUP BY t.cod_tipo_trecho, Trunc( t.Dat_inicio ) 
   ) transfProg, 

   (  SELECT (SUM ((a.qtd_cons_ating + a.qtd_cons_prim_ating + a.qtd_cons_rur_ating) * a.min_duracao ) / 60) valtrans, t.cod_tipo_trecho, 
           Trunc( t.Dat_inicio ) AS Dat_inicio 
      FROM tinter_intertrecho t, 
                ttransferenciaconint a, 
                titensinter i 
      WHERE t.dat_inicio >=  TRUNC(TO_DATE(mês_ANO,'MM/YYYY')) 
      AND   t.dat_inicio < TRUNC(LAST_DAY(TO_DATE(mês_ANO,'MM/YYYY')),'DD')+1 
      AND   t.num_id_interrupcao = i.num_id_interrupcao 
      AND   i.num_id_interrupcao = a.num_id_interrupcao 
      AND   i.num_id_item = a.num_id_item 
      AND   i.num_id_hierarquia IN 
                  ( SELECT DISTINCT num_id_hierarquia 
                     FROM tpotencia 
                     WHERE cod_conj_aneel_2001 = COD_ANEEL 
                     AND dat_refer >= TRUNC(To_Date(mês_ANO,'MM/YYYY')) 
                     AND dat_refer < TRUNC(LAST_DAY(TO_DATE(mês_ANO,'MM/YYYY')),'DD')+1 
                  ) 
      AND   (NOT(t.num_idt_grupo_causas = 4 AND t.num_idt_causa_interrupcao = 7)) 
      AND   (NOT(t.num_idt_grupo_causas = 10)) 
      AND t.tag_prog_acid='A' 
      AND i.tag_mom_sus = NVL(TIPO_DURACAO,i.tag_mom_sus) 
      GROUP BY t.cod_tipo_trecho,   Trunc( t.Dat_inicio ) 
   )transfAcid , 

   (  SELECT  Count((t.num_id_interrupcao) - NVL(t.num_religam_calculado,0)) AS fAcid, 
               t.cod_tipo_trecho, 
               Trunc( t.Dat_inicio ) AS Dat_inicio 
      FROM  tinter_intertrecho t 
      WHERE t.num_id_interrupcao IN 
           ( SELECT DISTINCT i.num_id_interrupcao 
             FROM   titensinter i 
             WHERE  i.num_id_hierarquia IN 
                            ( SELECT DISTINCT p.num_id_hierarquia 
                              FROM tpotencia p 
                              WHERE p.cod_conj_aneel_2001 = COD_ANEEL 
                              AND p.dat_refer >= TRUNC(To_Date(mês_ANO,'MM/YYYY')) 
                              AND p.dat_refer < TRUNC(LAST_DAY(TO_DATE(mês_ANO,'MM/YYYY')),'DD')+1 
                            ) 
           ) 
      AND t.dat_inicio >=  TRUNC(TO_DATE(mês_ANO,'MM/YYYY')) 
      AND t.dat_inicio < TRUNC(LAST_DAY(TO_DATE(mês_ANO,'MM/YYYY')),'DD')+1 
      AND (NOT(t.num_idt_grupo_causas = 4 AND t.num_idt_causa_interrupcao = 7)) 
      AND (NOT(t.num_idt_grupo_causas = 10)) 
      AND t.tag_prog_acid = 'A' 
      AND t.tag_mom_sus = NVL(TIPO_DURACAO,t.tag_mom_sus) 
      GROUP BY t.cod_tipo_trecho, Trunc( t.Dat_inicio ) 

   ) freqAcid, 

   (  SELECT  Count((t.num_id_interrupcao) - NVL(t.num_religam_calculado,0)) AS fProg, 
               t.cod_tipo_trecho, 
               Trunc( t.Dat_inicio ) AS Dat_inicio 
      FROM  tinter_intertrecho t 
      WHERE t.num_id_interrupcao IN 
           ( SELECT DISTINCT i.num_id_interrupcao 
             FROM   titensinter i 
             WHERE  i.num_id_hierarquia IN 
                            ( SELECT DISTINCT p.num_id_hierarquia 
                              FROM tpotencia p 
                              WHERE p.cod_conj_aneel_2001 = COD_ANEEL 
                              AND p.dat_refer >= TRUNC(To_Date(mês_ANO,'MM/YYYY')) 
                              AND p.dat_refer < TRUNC(LAST_DAY(TO_DATE(mês_ANO,'MM/YYYY')),'DD')+1 
                            ) 
           ) 
      AND t.dat_inicio >=  TRUNC(TO_DATE(mês_ANO,'MM/YYYY')) 
      AND t.dat_inicio < TRUNC(LAST_DAY(TO_DATE(mês_ANO,'MM/YYYY')),'DD')+1 
      AND (NOT(t.num_idt_grupo_causas = 4 AND t.num_idt_causa_interrupcao = 7)) 
      AND (NOT(t.num_idt_grupo_causas = 10)) 
      AND t.tag_prog_acid = 'P' 
      AND t.tag_mom_sus = NVL(TIPO_DURACAO,t.tag_mom_sus) 
      GROUP BY t.cod_tipo_trecho, Trunc( t.Dat_inicio ) 
   ) freqProg 

 WHERE aux.cod_tipo_trecho  = tr.cod_tipo_trecho 
 AND aux.cod_tipo_trecho    = fecdecProg.cod_tipo_trecho (+) 
 AND aux.cod_tipo_trecho    = fecdecAcid.cod_tipo_trecho (+) 
 AND aux.cod_tipo_trecho    = transfProg.cod_tipo_trecho (+) 
 AND aux.cod_tipo_trecho    = transfAcid.cod_tipo_trecho (+) 
 AND aux.cod_tipo_trecho    = freqProg.cod_tipo_trecho   (+) 
 AND aux.cod_tipo_trecho    = freqAcid.cod_tipo_trecho   (+) 

 AND aux.dat_inicio         = fecdecProg.dat_inicio      (+) 
 AND aux.dat_inicio         = fecdecAcid.dat_inicio      (+) 
 AND aux.dat_inicio         = transfProg.dat_inicio      (+) 
 AND aux.dat_inicio         = transfAcid.dat_inicio      (+) 
 AND aux.dat_inicio         = freqProg.dat_inicio        (+) 
 AND aux.dat_inicio         = freqAcid.dat_inicio        (+) 

 AND aux.dat_inicio >= TRUNC(TO_DATE(mês_ANO,'MM/YYYY')) 
 AND aux.dat_inicio <  TRUNC(LAST_DAY(TO_DATE(mês_ANO,'MM/YYYY')),'DD')+1 
 AND Extract( YEAR FROM To_Date(aux.Dat_inicio) ) = cc.ano 
 AND Extract( MONTH FROM To_Date(aux.Dat_inicio) ) = cc.mês 
 GROUP BY To_Char(aux.dat_inicio,'DD/MM/YYYY') 
 ORDER BY To_Char(aux.dat_inicio,'DD/MM/YYYY'); 
Você acha que, dado esta estrutura, há alguma forma de melhorar a performance usando cursores ou algum outro recurso para as subqueries??

Obrigado mais uma vez.
nandosistemas
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 6
Registrado em: Ter, 14 Abr 2009 11:40 am
Localização: BH - MG

Ah, ia me esquecendo. O motivo da query ser dinâmica é que eu posso inserir e retirar pedaços da consulta de acordo com os parâmetros passados pelo usuário. Porém, tentei fazer utilizando a bind variable mas não fui muito feliz. Agarrei numa coisa. Tem como eu inserir estes pedaços usando IF e ELSE?

De maneira bem errada, segue mais ou menos o que eu quero:

Selecionar tudo

OPEN cv_1 FOR

   'with h as ( SELECT l.COD_LOCAL FROM tOrdemHierarquia s
                inner join tOrdemHierarquia r ON ( s.COD_LOCAL=  r.NUM_ID_PAI )
                inner join tOrdemHierarquia l ON ( r.COD_LOCAL = l.NUM_ID_PAI )
                WHERE s.COD_LOCAL= (SELECT DISTINCT num_id_hierarquia FROM thierarquia WHERE cod_Hierarq=CAST(HIERARQUIA AS INT))

                UNION

                SELECT l.COD_LOCAL FROM tOrdemHierarquia s
                inner join tOrdemHierarquia r ON ( s.COD_LOCAL=  r.NUM_ID_PAI )
                inner join tOrdemHierarquia l ON ( r.COD_LOCAL = l.NUM_ID_PAI )
                WHERE r.COD_LOCAL= (SELECT DISTINCT num_id_hierarquia FROM thierarquia WHERE cod_Hierarq=CAST(HIERARQUIA AS INT))

                UNION

                SELECT l.COD_LOCAL FROM tOrdemHierarquia s
                inner join tOrdemHierarquia r ON ( s.COD_LOCAL=  r.NUM_ID_PAI )
                inner join tOrdemHierarquia l ON ( r.COD_LOCAL = l.NUM_ID_PAI )
                WHERE l.COD_LOCAL= (SELECT DISTINCT num_id_hierarquia FROM thierarquia WHERE cod_Hierarq=CAST(HIERARQUIA AS INT)
              )
          
     SELECT To_Char(aux.dat_inicio,''DD/MM/YYYY'')AS dat_inicio,
      Round( sum((NVL (fecdecProg.valdec,0) - NVL (transfProg.valtrans,0)) / DECODE (cc.pot,NULL,1,0,1,cc.pot)),10) AS Dec_Prog,
      Round(sum ((NVL (fecdecAcid.valdec,0) - NVL (transfAcid.valtrans,0)) / DECODE (cc.pot,NULL,1,0,1,cc.pot) ),10) AS Dec_Acid,
      Round ( Sum (((NVL (fecdecProg.valdec,0) - NVL (transfProg.valtrans,0)) / DECODE (cc.pot,NULL,1,0,1,cc.pot) ) +
           ((NVL (fecdecAcid.valdec,0) - NVL (transfAcid.valtrans,0)) / DECODE (cc.pot,NULL,1,0,1,cc.pot))),10) AS DEC_Total,


      FROM ttipotrecho tr,      
      (SELECT  (SUM (qtd_cons_distr +qtd_cons_prim +qtd_cons_rur) /1) pot,
       Extract( MONTH FROM dat_refer ) AS mês,
        extract( YEAR FROM dat_refer ) AS ano' ||

      IF(OPCAO = 2 AND HIERARQUIA IS NOT NULL) THEN

       'Concaneta alguma string'.
         
       END IF;

  ||   'Continua concatenando a consulta'
   
 END;
Tem como eu fazer isso?? Se eu concatenar a consulta em uma string eu consigo fazer isso perfeitamente. Mas usando a bind Variable com o cursor eu consigo?? Se der eu vou ganhar em performance e segurança.

Obrigado.
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 12 visitantes