Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

petrusmontes

Update em Procedure Oracle

Recommended Posts

Prezados estou com a seguinte procedure abaixo e não consigo aplicar update somente insert na tabela HISTPROC, não sei onde estou errando alguem poderia me ajudar? Ja fiz alguns debugs e na query principal tenho o retorno de mais de uma linha onde a ultima devia sofre um update na tabela temporia HISTPROC e não ocorre.

 

create or replace procedure AjustaHISTPROC
  (
   P_CDEMP         in PRONTUARIO_CAB.PC_CDEMP%type,
   P_CDBEN         in PRONTUARIO_CAB.PC_CDBEN%type
  )
is
   V_Idade          number(3)  := 0;
   V_CDPROC         string(11) := '';
   V_CDCLSPCMSO     number(1)  := 0;
   V_CDCLSPCMSO_AUX number(1)  := 0;
   
   V_PD_NR          number(8)  := 0;
   V_PD_CDPROC      string(11) := '';
   V_PD_RESULT      string(1)  := '';
   V_PD_DTAVAL      date;
   V_PD_OBS         string(80) := '';            
   V_PC_CDSETOR     number(4)  := 0;
   V_PC_CDPROFIS    number(4)  := 0;
   V_PC_CDCLSPCMSO  number(1)  := 0;
   V_PC_DTCONCLUSAO date;
   V_PC_CDEMP       number(3)  := 0;
   V_PC_CDSEQ       number(3)  := 0;
   V_COD_BEN        string(19) := '';            
   V_DTNASC         date;  
   
   V_FXED_NRPER1    number(4)  := 0;
   V_FXED_NRPER2    number(4)  := 0;
   V_FXED_NRPER3    number(4)  := 0;
   V_FXED_NRPER4    number(4)  := 0;  
   
   V_Ndias          number(4)  := 0;  
   
   V_PDO_CDPROC     PRONTUARIO_DETO.PDO_CDPROC%type;
   V_PDO_NDR        PRONTUARIO_DETO.PDO_NR%type;
   
   V_ProximaDt      date;
   
   V_HP_CDBEN          HISTPROC.HP_CDBEN%type;
   V_HP_DTPROXIMOEXAME HISTPROC.HP_DTPROXIMOEXAME%type;     
   V_HP_CONTADOR       HISTPROC.HP_CONTADOR%type;     

   cursor c_principal is   
      SELECT
             D.PD_NR         ,
             D.PD_CDPROC     ,
             D.PD_RESULT     ,
             D.PD_DTAVAL     ,
             D.PD_OBS        ,            
             C.PC_CDSETOR    ,
             C.PC_CDPROFIS   ,
             C.PC_CDCLSPCMSO ,
             C.PC_DTCONCLUSAO,
             C.PC_CDEMP      ,
             C.PC_CDSEQ      ,
             B.COD_BEN       ,
             B.DTNASC          
        FROM MOS.PRONTUARIO_CAB C,
             MOS.PRONTUARIO_DET D,
             MOS.BENEFICS_AUX   B  
       WHERE D.PD_NR          = C.PC_NR                    
         AND C.PC_CDBEN       = B.COD_BEN                  
         AND C.PC_DTCONCLUSAO IS NOT NULL                  
         AND D.PD_DTAVAL IS NOT NULL                       
         AND D.PD_TIPO        = 'C'                     
         AND C.PC_STATUS      = 'F'                     
         AND C.PC_CDEMP       = P_CDEMP
         AND C.PC_CDBEN       = P_CDBEN
       ORDER BY D.PD_DTAVAL;
   
   cursor c_funcxemp_det is   
      SELECT 
             FXED_NRPER1,
             FXED_NRPER2,
             FXED_NRPER3,
             FXED_NRPER4
        FROM MOS.FUNCXEMP_DET    
       WHERE FXED_CDEMP        = V_PC_CDEMP               
         AND FXED_CDSEQ        = V_PC_CDSEQ             
         AND FXED_CDCLSPCMSO   = V_CDCLSPCMSO_AUX         
         AND FXED_CDSETOR      = V_PC_CDSETOR             
         AND FXED_CDPROFIS     = V_PC_CDPROFIS          
         AND FXED_CDPROC       = V_PD_CDPROC;   
         
   cursor c_prontuario_deto is   
       SELECT
              PDO_CDPROC,
              PDO_NDR                   
         FROM MOS.PRONTUARIO_DETO
        WHERE PDO_TIPO         = 'C'         
          AND PDO_NR           = V_PD_NR
          AND PDO_CDCLSPCMSO   = V_CDCLSPCMSO   
          AND PDO_CDBEN        = V_COD_BEN      
          AND PDO_CDPROC       = V_PD_CDPROC;    
          
   cursor c_histproc is   
       SELECT
             HP_CDBEN           ,
             HP_DTPROXIMOEXAME  ,
             HP_CONTADOR    
        FROM MOS.HISTPROC       
       WHERE HP_CDEMP             = V_PC_CDEMP 
         AND TRIM(HP_CDBEN)       = TRIM(V_COD_BEN)
         AND TRIM(HP_CDPROC)      = TRIM(V_CDPROC)
         FOR UPDATE;       
   
begin

   DELETE 
     FROM MOS.HISTPROC
    WHERE HP_CDEMP = P_CDEMP;
    
   COMMIT;
       
   open c_principal;
   
   loop /* LOOP PRINCIPAL */
   
      fetch c_principal into V_PD_NR         ,
                             V_PD_CDPROC     ,
                             V_PD_RESULT     ,
                             V_PD_DTAVAL     ,
                             V_PD_OBS        ,            
                             V_PC_CDSETOR    ,
                             V_PC_CDPROFIS   ,
                             V_PC_CDCLSPCMSO ,
                             V_PC_DTCONCLUSAO,
                             V_PC_CDEMP      ,
                             V_PC_CDSEQ      ,
                             V_COD_BEN       ,
                             V_DTNASC        ;
                             
      exit when c_principal%notfound;

      V_Idade := ( sysdate - V_DTNASC )  / 365;

      V_CDPROC         := TRIM(V_PD_CDPROC);
      V_CDCLSPCMSO     := V_PC_CDCLSPCMSO;
      V_CDCLSPCMSO_AUX := V_PC_CDCLSPCMSO;
         
      if ( V_CDCLSPCMSO = 1 ) or    /* se admissioal...ou */ 
         ( V_CDCLSPCMSO = 2 ) or    /* se periodico...ou  */  
         ( V_CDCLSPCMSO = 3 ) or    /* se mudança de função...seta periodico...calcula ndias...ou */
         ( V_CDCLSPCMSO = 5 ) then  /* se retorno ao trabalho... */  
           if TRIM(V_CDPROC) = '90010014' then   /* se admissional...   */
              V_CDPROC      := TRIM('90010031'); /* Exame periodico.... */
           end if;

           if TRIM(V_CDPROC) = '90010031' then   /* se periodico...   */
              V_CDPROC      := TRIM('90010031'); /* Exame periodico.... */
           end if;

          if TRIM(V_CDPROC) = '90010049' then    /* se mudanca de função... */
             V_CDPROC      := TRIM('90010031');  /* Exame periodico.... */
          end if;

          if TRIM(V_CDPROC) = '90010045' then    /* se retorno ao trabalho...ou */
             V_CDPROC      := TRIM('90010031');  /* Exame periodico.... */
          end if;

          V_CDCLSPCMSO_AUX := 2; /* coloca classificacao auxiliar como periodico... */        
      end if;

      /* calcula o valor da variavel V_NDIAS... */

      V_Ndias := 0;

      open c_funcxemp_det;
   
      fetch c_funcxemp_det into V_FXED_NRPER1,
                                V_FXED_NRPER2,
                                V_FXED_NRPER3,
                                V_FXED_NRPER4;
      
       if c_funcxemp_det%found then
            if V_Idade < 18 then
               V_Ndias := V_FXED_NRPER1;
            end if;
            if V_Idade > 18 then
               V_Ndias := V_FXED_NRPER2;
            end if;
            if V_Idade < 45 then
               V_Ndias := V_FXED_NRPER3;
            end if;
            if V_Idade > 45 then
               V_Ndias := V_FXED_NRPER4;
            end if;
       end if;

       close c_funcxemp_det;
        
       if ( V_CDCLSPCMSO = 4 ) then    /* se demissional...ou */  
            V_Ndias := 0;
       end if;
       
      /* verifica se existe retorno para audiometria */  
      /* se existir reajusta a variavel V_NDIAS... */

      open c_prontuario_deto;
   
      fetch c_prontuario_deto into V_PDO_CDPROC,
                                   V_PDO_NDR   ;
   
       if c_prontuario_deto%found then
          V_Ndias := V_PDO_NDR;
       end if;

       close c_prontuario_deto;

       if ( V_CDCLSPCMSO = 4 ) then  /* se demissional...ou */  
            V_Ndias := 0;
       end if;

       /* calcula a nova data de retorno... */
       
/*     V_ProximaDt := V_PC_DTCONCLUSAO + V_Ndias; */

       V_ProximaDt := V_PD_DTAVAL + V_Ndias;
       
       /* verifica se existe historico do procedimento para o beneficiario... */
       /* se não existir faz um insert na tabela HISTPROC... */
       /* se existir faz um update na tabela HISTPROC... */
       
       open c_histproc;
   
       fetch c_histproc into V_HP_CDBEN         ,                        
                             V_HP_DTPROXIMOEXAME,
                             V_HP_CONTADOR;      
   
       if c_histproc%notfound then
          V_HP_CONTADOR := 1;
          INSERT INTO MOS.HISTPROC            
                                    (                         
                                     HP_CDEMP               ,
                                     HP_CDBEN               ,
                                     HP_NR                  ,
                                     HP_CDPROC              ,
                                     HP_CDSETOR             ,
                                     HP_CDPROFIS            ,
                                     HP_DTNASC              ,
                                     HP_IDADE               ,
                                     HP_DTAVAL              ,
                                     HP_DTCONCLUSAO         ,
                                     HP_DTPROXIMOEXAME      ,
                                     HP_NDIASRETORNO        ,
                                     HP_CONTADOR 
                                    )                         
                              VALUES                                            
                                    (                         
                                     V_PC_CDEMP              ,
                                     V_COD_BEN               ,
                                     V_PD_NR                 ,
                                     V_CDPROC                ,
                                     V_PC_CDSETOR            ,
                                     V_PC_CDPROFIS           ,
                                     V_DTNASC                ,
                                     V_Idade                 ,
                                     V_PD_DTAVAL             ,
                                     V_PC_DTCONCLUSAO        ,
                                     V_ProximaDt             ,
                                     V_Ndias                 ,
                                     V_HP_CONTADOR  
                                    );                        
         end if;
   
         if c_histproc%found then
            if V_ProximaDt > V_HP_DTPROXIMOEXAME then
               V_HP_CONTADOR := V_HP_CONTADOR + 1;
               UPDATE MOS.HISTPROC             
                  SET HP_NR             = V_PD_NR           ,
                      HP_CDSETOR        = V_PC_CDSETOR      ,
                      HP_CDPROFIS       = V_PC_CDPROFIS     ,
                      HP_DTNASC         = V_DTNASC          ,
                      HP_IDADE          = V_Idade           ,
                      HP_DTAVAL         = V_PD_DTAVAL       ,
                      HP_DTCONCLUSAO    = V_PC_DTCONCLUSAO  ,
                      HP_DTPROXIMOEXAME = V_ProximaDt       ,
                      HP_NDIASRETORNO   = V_Ndias           ,
                      HP_CONTADOR       = V_HP_CONTADOR   
                WHERE HP_CDEMP          = V_PC_CDEMP          
                  AND HP_CDBEN          = V_COD_BEN          
                  AND HP_CDPROC         = V_CDPROC;      
            end if;
         end if;

       commit;  
         
       close c_histproc;

   end loop; /* FIM DO LOOP PRINCIPAL */

   close c_principal;
   
end AjustaHISTPROC;

Compartilhar este post


Link para o post
Compartilhar em outros sites

não consigo aplicar update somente insert na tabela HISTPROC

O usuário que faz a operação tem grant de update na tabela ?

 

Existe alguma trigger de validação na tabela ?

 

Que erro que dá , dá algum erro ?

Compartilhar este post


Link para o post
Compartilhar em outros sites

não consigo aplicar update somente insert na tabela HISTPROC

O usuário que faz a operação tem grant de update na tabela ?

 

 

SIM O USUÁRIO TEM GRANT PARA UPDATE.

 

 

Existe alguma trigger de validação na tabela ?

 

 

EXISTE UMA TRIGGER QUE ATUALIZA UMA COLUNA CHAMADA HP_DT_LK QUE NADA MAIS É QUA A DATA E HORA DO ULTIMO INSERT OU UPDATE.

 

 

Que erro que dá , dá algum erro ?

 

O PROBLEMA QUE NÃO APRESENTA NENHUM ERRO, POREM DO RESULTSET PRINCIPAL EXISTE DUAS LINHAS ONDE A PRIMEIRA ESTA SENDO FEITO

O INSERT E A SEGUNDA QUE DEVERIA SER FEITO UM UPDATE NÃO OCORRE. SE você OBSERVAR EU FAÇO UM SELECT NA TABELA HISTPROC PARA

SABER SE DEVO APLICAR UM INSERT %NOFOUND OU UPDATE %FOUND.

 

 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Faça algo assim

 

  update tabela 
  where cod='01';
  if sql%count = 0 then -- não localizou no update
    insert into tabela (coluna) values('01');
  end if; 

Por algum motivo no caso que se devia inserir não está passando por esta lógica;

Compartilhar este post


Link para o post
Compartilhar em outros sites

Faça algo assim

 

  update tabela 
  where cod='01';
  if sql%count = 0 then -- não localizou no update
    insert into tabela (coluna) values('01');
  end if; 

Por algum motivo no caso que se devia inserir não está passando por esta lógica;

 

 

Obrigado pela dica, vou tentar.

 

Uma duvida, é correto a forma que eu montei o meu código? abrindo um curso para cada sql e montando um loop principal e abrindo e fechado os demais cursores e lendo o seu conteudo com fetch, sou novato e gostaria de saber se minha logica esta correta ou tem uma maneira melhor de fazer o que quero que é ler o conteudo de um sql que possui varias linhas e alimentar uma tabela temporaria.

 

Vcs poderiam me ajudar nessa analise do meu código?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Loops em geral só fazem sentido quando o Cursor precisa trazer mais de um registro , fora isto use um Select simples.

 

Em casos parecidos (alterar se existir , incluir senão existir) prefiro a lógica que te passei , se escreve menos.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.