Pular para o conteúdo
  • Este tópico contém 8 respostas, 5 vozes e foi atualizado pela última vez 17 anos atrás por Yoke.
Visualizando 9 posts - 1 até 9 (de 9 do total)
  • Autor
    Posts
  • #85356
    thianolima
    Participante

      Ola pessoal to aqui dinovo para ver se voces conseguem me ajudar.
      Aqui na empresa nos temos 2 dblink um para um banco de dados sqlServer e outro para outro banco Oracle. Criamos um banco Oracle que possue esses DBLink e o mesmo atraves de procedures ira consultar uma view de uma tabela do sql server ver se o registro esta no outro banco oracle caso exista atualiza caso nao insere. Nao utilizei Merge pois os dados sao duplcados na tabela do SQLServer sempre q alterado na tabela oficial q eu nao tenho acesso, tendo controle apenas por um flag q mostra para mim se o registro ja foi importado.
      Criei esta procedure abaixo:


      create or replace PROCEDURE PRC_IMPORTA_FUNCAO AS
      V_CONT INTEGER := 0;
      V_FNC_RECNO VW_SIG_FUNCAO.R_E_C_N_O_%TYPE;
      V_FNC_CODIGO VW_SIG_FUNCAO.CODIGO_FUNCAO%TYPE;
      V_FNC_DESCRICAO VW_SIG_FUNCAO.NOME%TYPE;

      -- SELECIONA OS DADOS DO MICROSIGA EM BAURU
      CURSOR V_CURSOR IS
      SELECT R_E_C_N_O_, CODIGO_FUNCAO, NOME
      FROM VW_SIG_FUNCAO;
      --WHERE INDPROCESSA_FINAN IS NULL OR INDPROCESSA_FINAN = '';
      BEGIN
      -- ABRE O CURSOR COM A SELECT FEITA NO MICROSIGA
      OPEN V_CURSOR;

      -- INICIA O LOOP DE ATUALIZACAO
      LOOP
      -- GUARDANDO OS VALORES DO REGISTRO
      FETCH V_CURSOR
      INTO V_FNC_RECNO, V_FNC_CODIGO, V_FNC_DESCRICAO;

      -- SAI DO LOOP QUANDO CHEGAR AO FIM DO CURSOR
      EXIT WHEN V_CURSOR%NOTFOUND;

      -- VERIFICA SE EXISTE NO ORACLE BAURU
      SELECT COUNT(*)
      INTO V_CONT
      FROM VW_ORA_FUNCAO
      WHERE FNC_RECNO = V_FNC_RECNO;

      -- SE NAO TIVER INSERIRE NO ORACLE DE BAURU
      IF((V_CONT <= 0) OR (V_CONT IS NULL))THEN INSERT INTO VW_ORA_FUNCAO(FNC_RECNO, FNC_CODIGO, FNC_DESCRICAO) VALUES(V_FNC_RECNO, V_FNC_CODIGO, V_FNC_DESCRICAO); -- SE NAO ATUALIZA O REGISTRO EXSITENTE NO ORACLE DE BAURU ELSE UPDATE VW_ORA_FUNCAO SET FNC_CODIGO = V_FNC_CODIGO, FNC_DESCRICAO = V_FNC_DESCRICAO WHERE FNC_RECNO = V_FNC_RECNO; END IF; -- ATUALIZA O BANCO COMMIT; END LOOP; -- FECHA O CURSOR PARA LIBERAR OS RECURSOS CONSUMIDOS CLOSE V_CURSOR; -- SE HOUVER ALGUM ERRO ELE VOLTA TUDO QUE FOI FEITO PARA NAO GRAVAR DADOS -- CORROMPIDOS NO BANCO DE DADOS EXCEPTION WHEN OTHERS THEN ROLLBACK; END PRC_IMPORTA_FUNCAO;

      Estou usando o SQLDeveloper e qdo debugo vejo q ele roda o primeiro registro aonde ele faz um UPDADE e ja no segundo registro qdo vai dar o fetch ele ja aborta td.
      Tenho outras 3 procedures identicas a estas para outras views que funcionam alguem poderia me ajudar com esse misterio?

      #85358
      Ishii
      Participante

        Olá,

        Adicione no exception dentro do when OTHERS:
        — Crie a Variavel vSqlErrm varchar2(2000)

        vSqlErrm := Sqlerrm;

        dbms_output.put_line (vSqlErrm);

        Ficaria assim:

        -- CORROMPIDOS NO BANCO DE DADOS
        EXCEPTION
        WHEN OTHERS THEN
        vSqlErrm := Sqlerrm;
        --
        dbms_output.put_line (vSqlErrm);
        --
        ROLLBACK;
        END PRC_IMPORTA_FUNCAO;

        No debug vc verifica o output ou ainda coloca o valor numa tabela temporária.

        Com isso fica mais fácil saber o erro que deve estar retornando no Update e abortando o cursor.

        []s Ishii

        #85359
        thianolima
        Participante

          ‘ORA-01002: extração fora de seqüência ORA-02063: precedendo line a partir de TESTESQL’

          Esta gerando este erro para mim, o TESTESQL e o meu dblink com o sqlserver, vc poderia me dizer oq isso significa?

          #85362
          Ishii
          Participante

            Olá,

            Por alguma razão o dblink está perdendo a conexão. Se a view VW_SIG_FUNCAO é que chama o dblink, tente rodar apenas a view e veja se ocorre algum erro…

            []s Ishii

            #85363
            David Siqueira
            Participante

              Teste seu db_link com uma query simples antes de rodar sua proc, de repente ele nem esta mais funcionando por alguma razão, e depois que tiver a certeza de seu db_link estar ok , reveja os passos indicados pelo Ishii.

              select * from tabela@TESTESQL;

              Abcs.

              David

              #85365
              thianolima
              Participante

                O DBLINK ta perfeito ja consegui fazer isso.
                Resolvi o erro de uma forma mta estranha li em um link http://ora-01002.ora-code.com/ q uns dos provaveis erros e q eu nao posso dar commit com o cursor aberto. Dai passei o commit para depois q eu dava o close no cursor e funcionou. Mas dai fiquei na duvida pq as outras views sao menores tendo cerca de 200 registros cada uma e elas nao deram erro dessa forma ja este que tem 10x mais 2000 mil registros deu esse erro. Alguem poderia me explicar melhor?

                #85386
                Rodrigo Mesquita
                Participante

                  Esse erro já aconteceu comigo. Acredito que na hora que vc da o fetch dentro de um loop e depois o commit. o fetch na proxima volta do cursor perde a sequencia dos dados consultados no cursor. Para evitar esse tipo de coisa procura usar o cursor com FOR e só da o commit ou na aplicação, ou no final da procedure

                  #85515
                  Yoke
                  Participante

                    Aproveitando o gancho, existe uma forma mais fácil de trabalhar com cursor, sem declarar nada e nem ficar controlando fetch:

                    begin

                     for  REG in (select ..... ) loop
                    
                           insert into BLABLABLA
                                          (campo1,
                                           campo2)
                                          values
                                          (REG.field2,
                                            REG.field3);
                           commit;
                    
                     end loop;
                    

                    end;

                    Exemplo bobo, funciona legal, se precisar controlar commit, use um contador e assim vai.
                    E o limite do fetch encadeado vai depender mais do open_cursors do parametro banco.

                    #85516
                    Yoke
                    Participante

                      create or replace PROCEDURE PRC_IMPORTA_FUNCAO AS
                      V_CONT INTEGER := 0;
                      BEGIN
                      -- INICIA O LOOP DE ATUALIZACAO
                      FOR V_CURSOR IN (SELECT R_E_C_N_O_ RECNO, CODIGO_FUNCAO CODIGO, NOME DESCRICAO
                      FROM VW_SIG_FUNCAO)
                      --WHERE INDPROCESSA_FINAN IS NULL OR INDPROCESSA_FINAN = '') LOOP
                      SELECT COUNT(*)
                      INTO V_CONT
                      FROM VW_ORA_FUNCAO
                      WHERE FNC_RECNO = V_CURSOR.RECNO;
                      -- SE NAO TIVER INSERIRE NO ORACLE DE BAURU
                      IF((V_CONT <= 0) OR (V_CONT IS NULL))THEN
                      INSERT INTO VW_ORA_FUNCAO(FNC_RECNO, FNC_CODIGO, FNC_DESCRICAO)
                      VALUES(V_CURSOR.RECNO, V_CURSOR.CODIGO, V_CURSOR.DESCRICAO);

                      -- SE NAO ATUALIZA O REGISTRO EXSITENTE NO ORACLE DE BAURU          
                      ELSE 
                        UPDATE VW_ORA_FUNCAO SET        
                          FNC_CODIGO = V_CURSOR.CODIGO, 
                          FNC_DESCRICAO = V_CURSOR.DESCRICAO 
                        WHERE FNC_RECNO = V_CURSOR.RECNO;        
                      END IF;                
                      

                      -- ATUALIZA O BANCO
                      COMMIT;
                      END LOOP;
                      -- SE HOUVER ALGUM ERRO ELE VOLTA TUDO QUE FOI FEITO PARA NAO GRAVAR DADOS
                      -- CORROMPIDOS NO BANCO DE DADOS
                      EXCEPTION
                      WHEN OTHERS THEN
                      ROLLBACK;
                      END PRC_IMPORTA_FUNCAO;

                    Visualizando 9 posts - 1 até 9 (de 9 do total)
                    • Você deve fazer login para responder a este tópico.