Verificando se valor já existe no banco

Fórum sobre a linguagem CA-Clipper.

Moderador: Moderadores

ClickOk
Usuário Nível 1
Usuário Nível 1
Mensagens: 13
Registrado em: 12 Jan 2017 21:29
Localização: Brasilia/DF

Verificando se valor já existe no banco

Mensagem por ClickOk »

Olá amigos

Tenho um requerimento de um cliente, que é assim: Tem um certo campo "CODIGO", onde ele quer que o usuário não possa adicionar um código repetido, isto é, que já exista no banco de dados. A linha é assim:

Código: Selecionar todos

 @  10, 10 GGET cCODIGO PICTURE "@!" VALID ! Empty(cCODIGO) MESSAGE "Informe o codigo (obrigatório)"
então, o que eu fiz: criei uma função

Código: Selecionar todos

FUNCTION CodigoExiste(codigo)
  nAreaAntiga := Select()
  DbSelectArea("Produtos")
  dbseek(codigo)
  achou := found()
  Select(nAreaAntiga )
return achou
e coloquei no VALID:

Código: Selecionar todos

 @  10, 10 GGET cCODIGO PICTURE "@!" VALID ! Empty(cCODIGO)  .and. !CodigoExiste(cCODIGO);
MESSAGE "Informe o codigo (obrigatório)"
A função está sendo chamada direitinho, mas deu um problema de indices. Daí descobri que o programador anterior não criou índices para o campo CODIGO (criou para outros campos), por isso provavelmente o dbseek nem funciona nesse caso.

Como é uma tabela grande, e locate é inviável, preciso criar um indice para usar apenas nesse trecho de código. E tem que ser de um jeito mais ou menos assim:
1) Guardar indice atual
2) Usar novo indice
3) restaurar indice antigo quando acabar de usar

Isso porque é um sistema existente e complexo, então não posso correr o risco de não de colocar de volta o indice anterior. Viram como salvei a area antiga e depois restaurei? parecido...

Agradeço antecipadamente!
Fábio Alves
"O homem lança os dados, mas do SENHOR procede o resultado" Provérbios 16:33 (paráfrase)
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Verificando se valor já existe no banco

Mensagem por alxsts »

Olá!

Se é uma tabela grande, não é recomendável criar índice a cada execução. Crie um índice permanente e use sempre que precisar. Nem precisa de função no VALID. Veja:

Código: Selecionar todos

   10, 10 GET cCODIGO ;
      PICTURE "@!" ;
        VALID (! Empty(cCODIGO) .AND. If( Produtos->( DbSeek( cCODIGO ) ), Alert( "Código já cadastrado" ) == -1, .T. ) ) ;
      MESSAGE "Informe o codigo (obrigatório)"
Quando se usa o operador ALIAS ( -> ) o próprio Clipper controla a alteração e restauração da área corrente.

O único cuidado que você precisará tomar será verificar todos os programas que incluam, excluam ou alteram registros nesta tabela e abrir em cada um deles o novo índice que irá criar. Caso contrário, os índices não serão atualizados.
[]´s
Alexandre Santos (AlxSts)
ClickOk
Usuário Nível 1
Usuário Nível 1
Mensagens: 13
Registrado em: 12 Jan 2017 21:29
Localização: Brasilia/DF

Verificando se valor já existe no banco

Mensagem por ClickOk »

Obrigado, alexandre. Sua reposta ajudou muito!

Só mais uma dúvida. Você disse "Crie um índice permanente e use sempre que precisar.". Mas não vejo o código de criação dos indices no código do antigo programador... e quando ele vai usar o índice, ele usa "dbsetindex()" (e pelo que vi na documentação do clipper, já está ultrapassado).

Que eu me lembre, para criar e usar índices, eu usava "INDEX ON .. TO" e "SET INDEX TO"... Então, estou meio confuso... Pode, por favor, dar um exemplo simples de como que faço para criar e usar um índice?
Fábio Alves
"O homem lança os dados, mas do SENHOR procede o resultado" Provérbios 16:33 (paráfrase)
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Verificando se valor já existe no banco

Mensagem por alxsts »

Olá!
ClickOk escreveu:Mas não vejo o código de criação dos indices no código do antigo programador...
Este sistema onde você está fazendo alterações deve ter uma rotina de criação e recriação de índices. Isto é comum em sistemas escritos em Clipper. Procure.

Nesta rotina, já deve ter a criação dos índices da tabela em questão (Produtos, pelo que deduzi do código postado). Acrescente então o código para criar mais um índice. Algo assim se estiver usando o driver DBFNTX:

Código: Selecionar todos

USE Produtos EXCLUSIVE NEW
INDEX ON codigo TO prodCod
USE
Verificar todos os programas que utilizam esta tabela e acrescentar a abertura de mais um índice. Isto fica fácil com um editor de texto que tenha "Find in Files". Algo assim:

Código: Selecionar todos

USE Produtos SHARED NEW
SET INDEX TO ind1, ind2, ind3....., prodCod
Quanto ao SET INDEX versus DbSetIndex(), é uma questão de escolha. Não sei qual documentação você leu mas não há nada de ultrapassado com elas. SET INDEX é um comando que, durante a compilação, é substituído pela função DdSetIndex(). Muitas funcionalidades do Clipper estão disponíveis na forma de comando ou função.
[]´s
Alexandre Santos (AlxSts)
ClickOk
Usuário Nível 1
Usuário Nível 1
Mensagens: 13
Registrado em: 12 Jan 2017 21:29
Localização: Brasilia/DF

Verificando se valor já existe no banco

Mensagem por ClickOk »

Obrigado, ajudou bastante!

Quanto a estar ultrapassado, li nesses docs:
https://harbour.github.io/ng/c53g01c/ng3228f.html
DBSETINDEX() is a compatibility command and therefore is not
recommended. It is superseded by the ORDLISTADD() function.
Fábio Alves
"O homem lança os dados, mas do SENHOR procede o resultado" Provérbios 16:33 (paráfrase)
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Verificando se valor já existe no banco

Mensagem por alxsts »

Olá!

Isto é verdade a partir do Clipper 5.3 e Harbour ou xHarbour. Se você usa Clipper 5.2 ainda são atuais.
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

Verificando se valor já existe no banco

Mensagem por rochinha »

Amiguinhos,

As diferenças entre o dbSetIndex() e o OrdListAdd() é que dbSetIndex() seria uma função definitiva enquanto o OrdListAdd() é uma função on-the-fly.

Explicando melhor cada chamada dbSetIndex() refaz a mesma enquanto OrdListAdd() permite adicionar ordens a lista existente. Como quando se adiciona valores a um vetor. Mutio melhor que dbSetIndex().
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Responder