Página 2 de 2

No. do pedido repetido

Enviado: 31 Out 2013 18:40
por Stanis Luksys
Sim,

A função tenta travar o arquivo inteiro, o que significa que mesmo que exista um usuário utilizando outro registro, ela não consegue travar. Quanto maior o tempo deste parâmetro, mais tempo ela fica em loop, e maior a chance de outro usuário pegar o mesmo número.

Neste caso do exemplo, não consegui entender a necessidade de travar o arquivo inteiro.

Eu acho que seria melhor algo do tipo:

Código: Selecionar todos

dbgobottom() 
DO WHILE .T.
  sPedido:=Pedido+1
  If ! DbSeek(sPedido)
        dbappend()
	     replace pedido     with SPEDIDO
	     dbunlock() 
   endif	 
enddo
Abraços

No. do pedido repetido

Enviado: 31 Out 2013 23:05
por marcos.gurupi
Obrigado pela resposta.
Bom eu uso assim a muito, muito tempo; mas é claro que preciso estah aberto para novas possibildades.
Agora eu imagino/imaginava que é necessário o travamento do arquivo para uma inclusão, principalmente por que tem a necessidade de um dbappend(), quando eu estou alterando ou excluindo um registro ai sim eu uso travar somente o registro em questao. Estou errado ?

No. do pedido repetido

Enviado: 01 Nov 2013 13:20
por Stanis Luksys
marcos.gurupi escreveu:Agora eu imagino/imaginava que é necessário o travamento do arquivo para uma inclusão, principalmente por que tem a necessidade de um dbappend(), quando eu estou alterando ou excluindo um registro ai sim eu uso travar somente o registro em questao. Estou errado ?
Sim, não é necessário travar o arquivo para criar novo registro, o próprio DbAppend() se encarrega de travar o registro que será gravado. Um DbAppend() é a mesma coisa que isso:

Código: Selecionar todos

DbGoBottom()
DbSkip()
RLock()
Abraços.

No. do pedido repetido

Enviado: 01 Nov 2013 15:50
por MARCELOG
Oi Marcos,
quando trabalhava com dbf e precisava de número único usava um arquivo texto em separado que também era integralmente bloqueado.
Era uma rotina disponibilizada no site caclipperwebsite.
Lá também tinha uma dica bem legal acerca de utilização do sistema em rede de computadores (registro fantasma, atualização perdida, etc.).
Já a proposta do Stanis funciona, todavia não é 100%, podendo ocorrer a duplicidade não desejada.
O dbf não tem recurso de campo "unique".
E é isso que você quer não é?
Ou seja, que o campo (coluna) pedido do arquivo pedido tenha números sequenciais sem repetição.
Então, sem o travamento do arquivo, dois ou mais usuários poderão gravar o mesmo sPedido definido num mesmo momento anterior.
Espero ter ajudado.

MarceloG

No. do pedido repetido

Enviado: 01 Nov 2013 16:09
por Stanis Luksys
Veja bem,

Acho que está ocorrendo uma confusão. Travar o arquivo não serve de nada, pois o travamento de DBF via flock(), não impede que outro usuário "leia" o arquivo, não é a mesma coisa que abrir exclusivo, e portanto outro usuário pode pegar o mesmo número de qualquer jeito.

Claro que o ideal é se fazer um controle externo, como já foi sugerido, através de uma outra tabela que contenha as sequencias, ou mesmo por um txt, etc.

O exemplo que eu dei foi só no intuito de aprimorar o código que foi apresentado, que contem alguns erros de lógica que aumentam o tempo entre pegar o número e gravar no banco. Quanto maior este tempo, maior a chance de duplicidade.

No. do pedido repetido

Enviado: 01 Nov 2013 16:42
por MARCELOG
Oi Marcos,
a situação de pesquisa, inserção e gravação de novo registro é rápida.
Por isso a proposta do Stanis funciona.
Mas como todas, inclusive a que tinha postado anteriormente não é 100% e/ou compromete o desempenho em rede com a necessidade de abertura do arquivo de dados no modo exclusivo.
O dbf não tem recurso de campo "unique".
E é isso que você quer não é?
Ou seja, que o campo (coluna) pedido do arquivo pedido tenha números sequenciais sem repetição.
Então, analisando mais detidamente o seu problema, acho que a melhor técnica é utilizar um arquivo texto em separado, que grava o número do pedido.
Quando utilizava dbf eu usava uma função que fazia isso, obtida no site caclipperwebsite.
Deu até saudade...
Fui lá e peguei ela prá você.
É muito simples o uso...

Código: Selecionar todos

FUNCTION NOVOCOD(ARQUIVO)
IF !FILE(ARQUIVO)
__nHandle := FCREATE(ARQUIVO, 0)
__IF FERROR() # 0
____ALERT("Erro"+ALLTRIM(STR( FERROR() ))+": Arquivo não pode ser criado!!!" )
____QUIT
__ELSE
____FWRITE(nHandle, "000000")
____FCLOSE(nHandle)
__ENDIF
ENDIF
nHandle := FOPEN(ARQUIVO, 18)
IF FERROR() != 0
__ALERT("Erro"+ALLTRIM(STR( FERROR() ))+": Arquivo não pode ser aberto!!" )
__QUIT
ENDIF
nCOD := VAL( FREADSTR(nHANDLE, 6) )
nCOD++
FSEEK(nHANDLE, 0)     
FWRITE(nHANDLE, STRZERO(nCOD,6))
FCLOSE(nHANDLE)
RETURN (nCOD)
Espero ter ajudado.

MarceloG

PS: tinha feito confusão mesmo.