GARANTIR DESCONTO

Fórum SELECT dentro de LOOP #497863

15/10/2014

0

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

Responder

Post mais votado

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...

Marisiana Battistella

Marisiana Battistella
Responder

Gostei + 1

Mais Posts

22/10/2014

Andre Teixeira

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.
Responder

Gostei + 0

22/10/2014

Marisiana Battistella

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

Gostei + 0

04/02/2015

Andre Teixeira

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.
Responder

Gostei + 0

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

Aceitar