- Este tópico contém 9 respostas, 3 vozes e foi atualizado pela última vez 18 anos atrás por
Marcio68Almeida.
-
AutorPosts
-
4 de março de 2008 às 5:42 pm #81327
Wendel
ParticipantePessoal, tenho uma aplicação em Visual Basic que de vez em qdo acontece algumas inconsistencias no BD Oracle.
Eu acredito que o problema seja, no código abaixo:
cnnDados.Execute “DELETE PROCESSO_SOS WHERE CD_SOS = ” & Cod_SOS
cnnDados.Execute “INSERT INTO GRA.PROCESSO_SOS (CD_PROCESSO, CD_SOS)
VALUES(” & cboProcesso.Column(0, cboProcesso.ListIndex) & “,” & Cod_SOS & “)Esse código é quando eu preciso mudar uma SOS de processo, o sistema apaga a linha onde a SOS antiga está e insere uma linha nova, com o novo processo da SOS. Segue a definição da Tabela:
TABELA PROCESSO_SOS
——————————
CD_PROCESSO : integer
CD_SOS : integerAcontece que algumas vezes, o DELETE não funciona, somente a inserção. Ai que está o probema,pois uma SOS não pode aparecer em 2 processos. Será que não poderia ser que algum outro usuário esteja usando a tabela, dai o sistema não consegue deletar a linha e somente inserir (mas isso é só as vezes)? Alguem saberia informar se é esse o problema, e uma possivel solução? Obrigado
[]’s WendelE com update em vez de deletar e inserir, poderia evitar isso.
4 de março de 2008 às 5:55 pm #81329Ishii
ParticipanteWendel,
Bom dia,
Um erro muito comum em aplicações está na definição do Modelo de Dados. Com o Modelo de Dados mal-definido ou com falta de informações para sua definição, pode gerar estas “inconsistências” no Banco de Dados. Com as informações que você nos passou aqui posso apenas supor que não há uma chave na Tabela PROCESSO_SOS tipo Unique Key na coluna CD_SOS, com isso apenas, conforme a regra que foi passada no tópico de uma SOS não pode ter dois processos, já seria suficiente para não ocorrer a inconsistência nesta tabela e ainda você conseguiria identificar melhor se o problema não está na Aplicação no momento do Delete, nas poucas vezes que tive que utilizar Aplicações em VB vi algumas coisas do tipo “não atualiza” ou “não apaga” também… mas o problema estava na conexão com o Oracle…
[]s Ishii
4 de março de 2008 às 6:07 pm #81332Wendel
ParticipantePessoal essa tabela não tem restrições, tipo que não pode ter 2 codigo de sos em 2 linhas. O problema é que o sistema está em produção e não posso mudar a definição da tabela. Segue a definição da tabela.
CREATE TABLE PROCESSO_SOS
(
CD_PROCESSO INTEGER NOT NULL,
CD_SOS INTEGER NOT NULL
)ALTER TABLE PROCESSO_SOS ADD (
CONSTRAINT REL_CD_PROCESSO_SOS
FOREIGN KEY (CD_PROCESSO)
REFERENCES PROCESSO (CD_PROCESSO));ALTER TABLE PROCESSO_SOS ADD (
CONSTRAINT REL_CD_SOS
FOREIGN KEY (CD_SOS)
REFERENCES SOS (CD_SOS));[]’s Wendel
4 de março de 2008 às 6:15 pm #81333Marcio68Almeida
ParticipanteBom…
Você pode/deve fazer duas coisas….
1. Adicionar uma PK, como disse o nosso amigo, isso evitará duplicidades.
2. Acertar o programa para testar os processos executados, isto é, verificar se a exclusão foi efetivada corretamente, aí então proceder a inclusão, se a exclusão der qualquer tipo de erro, enviar mensagem e não prosseguir.4 de março de 2008 às 6:20 pm #81334Ishii
ParticipanteWendel,
Seria possível então adicionar o “COMMIT” após o DELETE e o INSERT?
Pois com certeza o Oracle não está ignorando os comandos e não conseguindo deletar a tabela, mas pode ser que o Comando de DELETE não esteja sendo executado…
[]s Ishii
4 de março de 2008 às 6:40 pm #81335Wendel
ParticipantePessoal, não posso criar um PK na tabela, pois o sistema está em produção e eu não tenho permissão para isso. O que posso fazer é alterar o código da aplicação.
Antes a aplicação estava fazendo BeginTrans e CommitTrans no bloco inteiro (recurso do VB para fazer tratar uma transação com o BD). Minha intensão é fazer isso parcialmente para ver se resolve. Vejam o que acham da solução:
Versão anterior
cnnDados.Errors.Clear
On Error GoTo rollback
cnnDados.BeginTranscnnDados.Execute “DELETE PROCESSO_SOS WHERE CD_SOS = ” & Cod_SOS
cnnDados.Execute “INSERT INTO GRA.PROCESSO_SOS (CD_PROCESSO, CD_SOS)
VALUES(” & cboProcesso.Column(0, cboProcesso.ListIndex) & “,” & Cod_SOS & “)cnnDados.CommitTrans
============================================
versão nova
cnnDados.Errors.Clear
On Error GoTo rollback
cnnDados.BeginTranscnnDados.Execute “DELETE PROCESSO_SOS WHERE CD_SOS = ” & Cod_SOS
cnnDados.CommitTrans
cnnDados.Errors.Clear
On Error GoTo rollback
cnnDados.BeginTranscnnDados.Execute “INSERT INTO GRA.PROCESSO_SOS (CD_PROCESSO, CD_SOS)
VALUES(” & cboProcesso.Column(0, cboProcesso.ListIndex) & “,” & Cod_SOS & “)cnnDados.CommitTrans
4 de março de 2008 às 6:43 pm #81336Marcio68Almeida
ParticipanteDepois de dar um commit não é mais possível dar um rollback…
Não entendo de VB, mas se você testa depois do commit, o código de erro vai se referir ao commit e não ao delete, não é ???4 de março de 2008 às 6:51 pm #81337Wendel
ParticipanteMarcio na verdade ali é assim mesmo que o VB trabalha, aquele ROLLBACK ele executa se der algum erro na transação, ou seja, se não conseguir dar o COMMIT.
Estava analisando, e acho que vou usar essa outra solução, a que usa UPDATE, pois evita problema de não deletar a linha. Vejam o que acham, segue:
versão nova 2
cnnDados.Errors.Clear
On Error GoTo rollback
cnnDados.BeginTranscnnDados.Execute “UPDATE PROCESSO_SOS SET CD_PROCESSO = WHERE CD_SOS = ” & Cod_SOS &”
cnnDados.CommitTrans
4 de março de 2008 às 7:00 pm #81338Ishii
ParticipanteWendel,
Acho que o UPDATE é a única solução no seu caso, uma vez que não é possível alterar o Banco…como eu disse antes… com o VB não tive boas experiências com o Oracle justamente por causa destas tratativas de transações gerenciadas pelo VB e não pelo Banco de Dados..
[]s Ishii
4 de março de 2008 às 7:11 pm #81339Marcio68Almeida
ParticipanteEssa certamente é a melhor opção, pois evita fragmentação da tabela.
É muito interessante que se coloque índices, mesmo que não sejam índices únicos, pois full table scan é assassinato… 😀 -
AutorPosts
- Você deve fazer login para responder a este tópico.