- Este tópico contém 8 respostas, 5 vozes e foi atualizado pela última vez 17 anos atrás por
Yoke.
-
AutorPosts
-
18 de fevereiro de 2009 às 7:30 pm #85356
thianolima
ParticipanteOla 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?18 de fevereiro de 2009 às 8:58 pm #85358Ishii
ParticipanteOlá,
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
18 de fevereiro de 2009 às 9:30 pm #85359thianolima
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?
18 de fevereiro de 2009 às 9:55 pm #85362Ishii
ParticipanteOlá,
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
18 de fevereiro de 2009 às 9:58 pm #85363David Siqueira
ParticipanteTeste 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
18 de fevereiro de 2009 às 10:23 pm #85365thianolima
ParticipanteO 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?19 de fevereiro de 2009 às 9:56 pm #85386Rodrigo Mesquita
ParticipanteEsse 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
28 de fevereiro de 2009 às 4:45 pm #85515Yoke
ParticipanteAproveitando 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.28 de fevereiro de 2009 às 10:01 pm #85516Yoke
Participantecreate 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; -
AutorPosts
- Você deve fazer login para responder a este tópico.