Página 1 de 1
Como utilizar Begin Sequence e Try
Enviado: 11 Abr 2012 22:03
por carlos_dornelas
Caros, estou precisando implementar uma rotina que me dê muita segurança para atualizar alguns dbfs sequencialmente. Tipo, se no meio do caminho algo inesperado acontecer, que as alterações iniciadas envolvendo atualização de registros e adição de novos registros, sejam desfeitas automaticamente. Será isso possível utilizando os controles abaixo ou através de outras funções? Alguém teria algum exemplo simples de utilização desses controles?
Grato
Antonio Carlos
Curitiba
BEGIN SEQUENCE
<statements_Normal>
[ BREAK [<expression>] ]
[ RECOVER [USING <errorVar>]
<statements_Error>
]
END[SEQUENCE]
TRY
<statements>
[THROW( <oErrorObject> )]
[CATCH [<thrownError>]
<errorHandling>
[FINALLY
<guaranteed> ]
END
Como utilizar Begin Sequence e Try
Enviado: 13 Abr 2012 19:33
por carlos_dornelas
O pessoal, dá uma força aí...
Como utilizar Begin Sequence e Try
Enviado: 13 Abr 2012 20:04
por Pablo César
para atualizar alguns dbfs sequencialmente. Tipo, se no meio do caminho algo inesperado acontecer, que as alterações iniciadas envolvendo atualização de registros e adição de novos registros, sejam desfeitas automaticamente
Apenas minha opinião. Acredito que esse recurso a base de dados em dbf não possui DTL - Linguagem de Transação de Dados como o SQL por exemplo. Portanto, qualquer rotina do tipo ROLLBACK, deve ser feito de forma artesanal e o seu funcionamento seria totalmente diferente como é dado num SGBD.
Como utilizar Begin Sequence e Try
Enviado: 13 Abr 2012 20:16
por alxsts
Olá!
Carlos, você até pode utilizar estes blocos de comandos citados mas, isso sozinho não vai resolver o teu problema. Funcionaria muito bem em um banco de dados relacional, que não é o caso dos DBFs, onde uma transaction poderia ser aberta. Se todos os passos do processo fossem concluídos (Try), você encerraria com um commit. Caso contrario (Catch) você emitiria um rollback.
No caso presente, sugiro que você use o tradicional conceito de balance line. Neste tipo de processamento, você tem o arquivo de entrada (que é o teu DBF original), o arquivo de movimentações (inclusões,alterações e exclusões a serem feitas) e o arquivo de saída, que nada mais é que o arquivo original atualizado com as movimentações. Se algo der errado, é só reprocessar.
Mais dúvidas? Continue postando.
Como utilizar Begin Sequence e Try
Enviado: 13 Abr 2012 20:36
por Pablo César
Só para complementar, adicionando mais uma ideia. Para o caso do bd ser dbfs, talvez no caso de persistência seja mais coerente fazer uma rotina de verificação do registro que foi gravado comparando com a rotina de verificação de integridade dos dados gravados, utilizando-se por exemplo do MD5 (como o colega Maligno já sugeriu há tempo atrás), veja:
https://pctoledo.org/forum/viewto ... md5#p25469
Como utilizar Begin Sequence e Try
Enviado: 14 Abr 2012 19:04
por carlos_dornelas
Colegas, grato pelas dicas! achei interessantea ideia do balance line, pois me pareceu ser bem facil implementar no meu caso. Mas soh me resta a duvida quantos aos comandos objeto deste topico. Em que casos seria interessante utiliza-los (interrogacao)
Como utilizar Begin Sequence e Try
Enviado: 14 Abr 2012 20:38
por ANDRIL
Voce poderia antes de iniciar o processo de atualização, fazer uma copia do dbf que ira modificar. Abra o dbf em modo exclusivo ou em fLock() e faça a copia e salve também os índices desse arquivo. Rode a sua rotina de atualizacao dentro do TRY/CATCH se ocorrer um erro, voce volta o arquivo copia para original junto com seus índices.
Faça um teste e veja se fica viável.
Abraços
Como utilizar Begin Sequence e Try
Enviado: 16 Abr 2012 07:44
por carlos_dornelas
Andril, grato pela sua dica. Eu ja tinha pensado no backup dos dbfs antes de iniciar o processo. Então voltamos para o IF ELSE ENDIF, não?
Como utilizar Begin Sequence e Try
Enviado: 16 Abr 2012 09:35
por ANDRIL
carlos_dornelas escreveu:Então voltamos para o IF ELSE ENDIF, não?
Amigo não entendi o que quiz dizer. Mas, pode usar o TRY/CATCH sem IF mesmo. Veja este exemplo:
Código: Selecionar todos
priv arqs:{{"clientes.atu","clientes.dbf","clientes.res"},;
{"produtos.atu","produtos.dbf","produtos.res"},;
{"fornece.atu","fornece.dbf","fornece.res"};
}
For i = 1 to len(arqs)
*| faz a copia do arquivo dbf a ser tratado
COPY FILE arqs[i,1] TO arqs[i,3]
TRY
SuaRotinadeAtualizacao(arqs[i,1],arqs[i,2])
CATCH
|* se ocorreu um erro, Restaura o arquivo reserva
COPY FILE arqs[i,3] TO arqs[i,1]
END
|* aqui se quiser pode apagar o arquivo reserva
ferase(arqs[i,3])
Next
Amigo, algumas consideracoes:
- tratei cada dbf individualmente, o ideal seria voce ter os indices desses dbfs pois no caso de
erro voce voltaria o reserva e recriava os indices para nao dar problema de corrupção. Este procedimento
pode ser deixado de lado, se voce abrir os dbf em modo EXCLUSIVO sem abertura dos indices, assim, os
indices nao seriam atualizados durante a atualizacao, ficando compativel com a copia reserva. Neste
caso, ao voltar a copia reserva basta reabrir os indices.
- este é um exemplo simplório, apenas para ter uma idéia.
Até+
Como utilizar Begin Sequence e Try
Enviado: 16 Abr 2012 10:51
por carlos_dornelas
Andril,
Com relação ao IF ELSE ENDIF, pensei no seguinte:
Código: Selecionar todos
Sucesso=0
MinhaFuncaoAtualiza()
**se houver algum problema, altero o valor de Sucesso=1
IF sucesso=0
OK, segue o programa
ELSE
DESFAZ, e retorna
ENDIF
Como utilizar Begin Sequence e Try
Enviado: 16 Abr 2012 11:14
por ANDRIL
Entendi, de qualquer forma para que voce possa alterar o conteudo da variavel Sucesso voce tera que usar uma estrutura de controle de erro como a TRY/CATH. Dependendo que como voce monte a sua funcao de atualizacao (processar um a um ou todos e reportar um erro) pode ser significativo a forma como postei acima.
Estude o método que seja mais viável pois voce tem o codigo e a lógica do negócio.
Boa sorte.
Como utilizar Begin Sequence e Try
Enviado: 16 Abr 2012 11:34
por carlos_dornelas
Andril, só uma última dúvida: no teu exemplo, você escreveu: " se ocorreu um erro, Restaura o arquivo reserva". Esse "erro" seria um erro de programa, daqueles que causa o encerramento do programa? Se é isso, começo a perceber a vantagem do TRY CATCH...
Como utilizar Begin Sequence e Try
Enviado: 16 Abr 2012 13:58
por ANDRIL
carlos_dornelas escreveu:Se é isso, começo a perceber a vantagem do TRY CATCH...
É isso ai. Esta é a vantagem desta estrutura. Ela monitora o run-time, quando o codigo entre TRY e CATH ocasiona um erro, gera uma "Exception" como diz em outras linguagens. Em outra estrutura como if, case por exemplo, ocorreria o erro e o programa seria abortado.
Vá treinando fazendo testes e logo voce dominará.
Abraços
Como utilizar Begin Sequence e Try
Enviado: 28 Abr 2012 14:23
por Stanis Luksys
Olá,
Depende do tamanho dos arquivos e o quanto eles são usados na rede. A forma mais simples que eu conheço de fazer isso, e que eu já usei com Harbour, foi a seguinte.
1 - Abre todos os DBFs envolvidos em modo exclusivo
2 - Abre o TRY e para cada DBF, antes de atualizar, faz o backup dele com FCopy ou COPY TO, e guarda só o nome dele numa matriz.
3 - Se der algum erro, varre a matriz restaurando os DBFS que foram alterados. Os que não foram alterados, não estarão na matriz. Tudo volta ao normal.
Uma outra forma, seria criar vários DBFs vazios com estruturas iguais aos originais (COPY STRUCTURE EXTENDED), e neste vazios apenas incluir o registro que foi alterado no original, como ele era antes da alteração. Se der erro, delete os que foram alterados e traz estes de volta.
Este segundo método é melhor pois não precisa abrir exclusivo, e não precisa fazer backup dos arquivos inteiros, o que atrapalharia em casos de DBFS grandes.
Abraços.