SELECT dentro de LOOP

Oracle

15/10/2014

Eu trabalho em uma empresa que usa o forms como ferramenta case para desenvolvimento de telas.

Umas dessas telas possui um botão que gera um excel com informações extraídas de diferentes tabelas.

A maioria dessas informações é possível pegar com um cursor mas há informações que estão sendo recuperadas dentro do loop.

Esse procedimento está levando muito tempo para ser concluído, chegando a demorar mais de 30 min para gerar o arquivo de texto.


Quero saber como eu posso modificar e/ou melhorar as buscas feitas dentro do LOOP para que não leve tanto tempo para gerar o arquivo!?!?!?

Abaixo o cursor


CURSOR Cur_itens IS
      SELECT A.CD...
           , replace(B.N..., '"', ' ') NM_IT...
           , A.DT_...
           , B.DT_I..
           , B.NO_RE..
           , replace(D.NM_SP_F.., '"', ' ') 
           , replace(c.NM_FA.., '"', ' ') 
           , A.ID_AT...  
           , E.nm_uni...
           , f.nm_uni...
           , A.VL_ITEM...
           , A.VL_IT...
           , A.DT_A...
           , A.QT_LO...    
           , A.QT_MI...
           , A.QT_MUL...
           , g.nm_CL...
           , c.PC_T...
           , c.id_...
           , REPLACE(b.T..., CHR(10), ' ') 
           , A.CD_I...
        FROM dco_ite... A
           , dco_rev.. B
           , dco_fa...  C
           , dco_s... D
           , unida... e
           , unida... f
           , clas_emb_vazia g
       WHERE A.CD_... = B.NM_...
         AND B.NO_REV_ITEM_UNICO = ( SELECT MAX(B1.NO_REV...)
                                       FROM dco_rev...B1
                                      WHERE B1.CD_IT... = B.CD_IT...)
         AND B.CD_SEQ...        = C.CD_SEQ...
         AND C.CD_SEQ_S...     = D.CD_SEQ_S...
         AND a.cd_se...      = e.cd_se...
         and a.CD_SEQ... = f.cd_seq..
         and A.CD_CL...     = g.CD_C...(+);

FOR Reg IN Cur_itens LOOP
 
--faço a impressão dos dados e os demais Selects para complementar o Arquivo

       pck_text_io.Put( ARQ_BR, ARQ_BR_WEB, Reg.item);
       pck_text_io.Put( ARQ_BR, ARQ_BR_WEB, ';' );

BEGIN
      SELECT COUNT(DISTINCT...

EXCEPTION
	  	WHEN OTHERS THEN
            ........

RAISE FORM_TRIGGER_FAILURE;  
	  END;


--São mais 5 como esse antes de encerrar

END LOOP;

Andre Teixeira

Andre Teixeira

Curtidas 0

Melhor post

Marisiana Battistella

Marisiana Battistella

15/10/2014

Imagino que essas informações estejam armazenadas na base de dados.... certo?
Então porque você não cria um SELECT buscando essas informações do banco de dados?
No caso de alguma informação se calculada naquele arquivo, tela, ou relatório, você faz o calculo novamente no SQL...

Acredito que a demora possa ser em função da quantidade de informações que há nos arquivos que ele tem que verificar...

Não sei se isso se aplica, mas espero ter contribuído...
GOSTEI 1

Mais Respostas

Andre Teixeira

Andre Teixeira

15/10/2014

Imagino que essas informações estejam armazenadas na base de dados.... certo?
Então porque você não cria um SELECT buscando essas informações do banco de dados?
No caso de alguma informação se calculada naquele arquivo, tela, ou relatório, você faz o calculo novamente no SQL...

Acredito que a demora possa ser em função da quantidade de informações que há nos arquivos que ele tem que verificar...

Não sei se isso se aplica, mas espero ter contribuído...


Obrigado pela atenção ao meu problema Marisiana mas creio que a razão do meu problema estaja na quantidade de SELECT executados dentro do LOOP.

Infelizmente eles são necessários. Eu só gastaria de saber se há uma forma menos demorada de executar tantos Select's diferentes dentro do LOOP sem ter muita demora na execução da query.
GOSTEI 0
Marisiana Battistella

Marisiana Battistella

15/10/2014

Uma forma de agilizar é utilizando os índices tendo cuidada de informar corretamente nos JOINs...
Boas práticas na criação dos SELECT também....
GOSTEI 0
Lourival Queiroz

Lourival Queiroz

15/10/2014

Vc pode criar o select e utiliza o "Explain Plan" para verificar a eficiência do mesmo. Utilizo para todos os selects que faço, e nunca tive problema de velocidade mesmo em joins de mutiplas tabelas com mais de 1 milhão de registros em cada. Observa também que a utilização de "views" ajuda muito na solução de velocidade das movimentações de dados.
GOSTEI 1
Andre Teixeira

Andre Teixeira

15/10/2014

Galera meu problema agora é outro.

Vejam se podem me ajudar.

Preciso reduzir o custo da query abaixo, que está em 65128 de acordo com o EXPLAIN PLAN do SQL Developer.
Isso faz com que a aplicação que executa essa busca demore muito para trazer os resultados.

SELECT DISTINCT CEE.CD_SEQ_EMP_UNICO,
         DECODE( EU.CD_TIPO, 'E', EM.NM_FUNCIONARIO, CO.NM_EMPRESA ) "NOME",
         DECODE( EU.CD_TIPO, 'E', EU.CD_MATRICULA, NULL )            "MATRICULA",
         DECODE( EU.CD_TIPO, 'E', EM.CD_SITUACAO_RH, NULL )          "SITUACAO",
         EU.CD_TIPO,
         EU.CD_SUPERVISOR
	  FROM CTRL_EPI_EMPREGADOS CEE,
	       EMPREG_UNICO EU,
	       EMPREGADO EM,
	       EMPRESA CO,
	       SIP_USUARIOS SU,
	       CAD_SETOR CS
   WHERE CEE.CD_SEQ_EMP_UNICO = EU.CD_SEQ_EMP_UNICO
     AND ( ( EU.CD_TIPO = 'E' and EM.CD_MATRICULA = EU.CD_MATRICULA ) OR
           ( EU.CD_TIPO = 'C' and CO.CD_EMPRESA   = EU.CD_CONTRATADO ) )   
     AND CEE.NM_USUARIO_INI = SU.NM_LOGIN_USUARIO                       
     AND SU.CD_SETOR = CS.CD_SETOR
     AND CS.CD_EMPRESA = :GLOBAL.LOCAL --> 10 ou 8
   ORDER BY 2;


Aguardo retorno.
Abraço.
GOSTEI 0
POSTAR