Página 1 de 1

Registros no DB

Enviado: 08 Nov 2007 13:15
por ederxc
Boa tarde !


Qual seria a forma de avaliar se existe algum registro em um DB ou seja , se ele esta zerado , nunca nada fui incluso nele ??

Enviado: 08 Nov 2007 13:19
por sygecom
USE AGENDA ALAIS AGENDA SHARED

SELE AGENDA
DBGOTOP()
IF BOF()
ALERT("VAZIO")
ENDIF

Enviado: 08 Nov 2007 14:20
por TerraSoftware
USE AGENDA ALIAS AGENDA SHARED

SELECT AGENDA
if lastrec()=0
ALERT("VAZIO")
ENDIF

Enviado: 08 Nov 2007 17:44
por Eolo
EderX,

Dar um parpite...

A primeira parte da sua pergunta ("Qual seria a forma de avaliar se existe algum registro em um DB") me parece que não fecha com a segunda parte ("se ele esta zerado, nunca nada fui incluso nele")... Um DBF zerado não quer dizer que "nunca nada foi incluso nele": você pode ter primeiro incluido um registro, depois ter deletado esse registro e depois rodado o PACK. Ao final, o DBF estará novamente "virgem", zerado...

Outra coisa: a função LASTREC() retorna o número de registros do DBF (que ela pega do header do arquivo), não importando se há registros DELETADOS ou não. Por exemplo, se vc tem 1.000 registros e todos os 1.000 estão deletados, LASTEREC() retorna 1.000, mesmo que vc esteja com SET DELE ON...



Bão, imagino que vc queira de fato saber se, em um determinado momento, um DBF tem algum registro ativo. É isso? Se for, esquece a LASTREC(). Aliás, esta função pode até ser a primeira checagem (veja abaixo)...

Duas opções:

a) usar o comando COUNT, que é demorado para DBFs grandes: COUNT TO XPTO FOR !DELETED() guarda em XPTO o número de registros ativos encontrados, mas pra fazer isso ele varre o arquivo todo, registro por registro... Haja!

b) indexar o seu DBF por um campo lógico chamado por exemplo DELETA e, quando vc deletar um registro, mudar o valor desse campo de .F. para .T. Depois, de vc quiser saber se tem algum registro deletado, é só fazer SEEK .T. (veja abaixo). Isto é muito mais rápido... Isto considerando que vc, periodicamente, roda um PACK em seus DBF, pra não ficar guardando lixo à toa.

Um exemplo, resumindo a coisa:

Código: Selecionar todos

use pedidos excl new
inde on deleta to pedidos
set inde to pedidos
do whil .t.
  if lastrec()=0 // DBF zerado
    alert("DBF com ZERO registros")
    exit
  end
  seek .t.
  if found()
    conta=1
    do whil .t.
      skip
      if deleta=.t.
        conta++
      else
        exit
      endi
    endd
    alert("DBF tem "+str(lastrec())+" registros, sendo "+str(conta)+" deletados")
  else
    alert("DBF tem "+str(lastrec())+" registros, todos ativos")
  endi
  exit
endd
quit

Enviado: 09 Nov 2007 04:11
por rochinha
Amiguinhos

E se simplesmente usarmos o RecCount():

USE AGENDA ALAIS AGENDA SHARED

SELE AGENDA
IF RECCOUNT() = 0
ALERT("VAZIO")
ENDIF

Enviado: 09 Nov 2007 08:14
por Eolo
A função RECCOUNT() traz exatamente o mesmo resultado que LASTREC().

Ambas "podem mascarar" a coisa: vc pode ter RECCOUNT() igual a 100 e todos esses 100 registros estarem deletados, então de fato vc "não tem" esses registros (que vão sumir no próximo PACK)...

Enviado: 09 Nov 2007 10:21
por rochinha
Amiguinho

Fiz o seguinte teste em uma tabela com 64 registros:

Código: Selecionar todos

use campalvo
? recco(), lastrec()
set dele on
? recco(), lastrec()
delete all
? recco(), lastrec()
pack
? recco(), lastrec()
O retorno foi

Código: Selecionar todos

   64    64
   64    64
   64    64
   0      0
Nenhuma delas levou em consideração os registros deletados. Então o negócio é testar um-a-um para o caso de contagem de registros válidos.

Enviado: 09 Nov 2007 11:37
por Eolo
Sim. Foi o que eu sugeri em meu primeiro post.

Enviado: 17 Nov 2007 17:21
por Eolo
Éric, matou a pau. Muito bem lembrado o uso do registro fantasma.

Mas diz uma coisa: vc não chegou a testar com FILTERs, INDEXações etc., pra confirmar que a coisa relamente funciona em qualquer situação?