Alterando o valor do generator via código delphi!

Firebird

14/12/2006

Pessoal, gostaria que os colegas me desse uma ajuda sobre como ajustar o valor do generator via delphi... Uso a peleta Interbase com o IbDataBases, IbTransaction e IbTables...

O motivo que o seguinte: Toda vez que excluir um registro, quero executar uma query para saber o maior valor da tabela e, de acordo com o resultado, excutar o código ´ SET GENERATOR [NOME_DO_GEN] TO VALOR

VALEU PESSOAL!


Cmtbravo

Cmtbravo

Curtidas 0

Respostas

Emerson Nascimento

Emerson Nascimento

14/12/2006

nesse caso você não precisa do generator.
CREATE trigger X for TABELA
active before insert position 0
AS
BEGIN
  IF (NEW.CAMPO IS NULL) THEN
    select coalesce(max(CAMPO),0)+1 from TABELA into NEW.CAMPO;
END


nunca entendi o porque desse controle...

e no seguinte caso:
registros
1
2
3
4
5

eu apago o 2, o 3 e o 4. quando eu incluir o seguinte, como fica?
1
5
6

do que adianta esse controle de numeração se pode ficar um ´buraco´ entre os registros?


GOSTEI 0
Cmtbravo

Cmtbravo

14/12/2006

fá tentei faze do jeito que vc falou, mas este comando ´coalesce´ dá pau quando executo na trigger, o interbase diz que não conhece..

O motivo de eu quere saber como alterar o valor do generator por dentro do projeto é simples ...

na minha trigger, quando excluo um registro, exemplo;

1
2
3

se excluo o 3, quando excluo novamente, ele cria o 4. Isso eu não quero que aconteca, então se eu puder fazer o seguinte:

selemact max(codigo) as vmax from tabela

pegar o valor máximo e setar o generator com ele :

set generator [nome] to [valor]

onde valor seria = ao valor maximo que a query me retornou... pra mim seria melhor entende.!!

mas valeu pela dica .. se vc tiver o código pra esta solução ficaria muito grato!!

Abraço!


GOSTEI 0
Raserafim

Raserafim

14/12/2006

emerson, muito embora os buracos na numeração possam parecer ilógicos, mas ocupar estes espaços não é uma medida segura. a razão para isso é a integridade.

imagine que vc tinha uma ordem de serviço cadastrado e o cliente tem um papel impresso desta ordem com o seu código. se vc apaga este registro e depois cria um outro e este mesmo número fosse ocupado, este outro cliente teria o mesmo código da ordem de serviço do outro cliente.

agora imagina uma outra situação. vc cadastraria um cliente e seus telefones. depois vc apaga este cliente e vc não tinha feito o relacionamento para a exclusão dos dados em cascata. depois quando vc cadastrar um outro cliente ele assumirá os telefones do cliente antigo.

ou seja, autonumeração tem que garantir uma numeração única para cada registro.


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

14/12/2006

foi exatamente o que eu quis dizer. esse controle é totalmente desnecessário.


GOSTEI 0
Raserafim

Raserafim

14/12/2006

este controle soluciona dois problemas:

1- utilizar o select max faz varrer a tabela inteira em busca do maior valor (tudo bem que o índice agilize este processo, mas de qualquer maneira tem que checar a tabela)

2- quando a aplicação funciona em rede e tem acesso concorrencial, esta medida (select max) pode provocar com muita frequência erro de duplicidade de primary key.
imagine se dois usuários abrir o form cadastro de clientes e tentarem salvar quase que no mesmo instante, os dois usuários irão receber o select max o mesmo valor.

este contador é imprescidível para uma aplicação em rede, pois desta forma o firebird garante a unicidade dos registros. e se vc quiser fazer o controle semi-automático, pegando o valor deste contador, o firebird tem uma função que ao ler este valor do contador ele já é incrementado.


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

14/12/2006

pois é... por isso esse valor deve ser gerado ao [b:78e42e6ce0]gravar[/b:78e42e6ce0] o registo. não ao incluir. seja via generator ou via ´selec max()´


GOSTEI 0
Raserafim

Raserafim

14/12/2006

sim, é verdade. o código deve ser apenas verificado e gravado no momento em que o registro for ser salvo.

mas o select max não impede que o mesmo valor seja resgatado por dois usuários. a probabilidade será maior ou menor quanto maior for a quantidade de usuários e quanto maior for o lag da rede, o processamento da aplicação, etc.

enquanto que com o contador, o simples fato de ler o valor já pode ser incrementado o valor, impossibilitando que dois usuários peguem o mesmo valor.


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

14/12/2006

se o ´select max´ não impede o generator também não...


GOSTEI 0
Raserafim

Raserafim

14/12/2006

analise com calma, e verá que estás equivocado


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

14/12/2006

raserafim, não estou falando do select max de uma forma genérica. estou falando que o select max tem o mesmo efeito do generator, desde que usado numa trigger, como no exemplo passado, e [b:e6f09fb27e]disparado no momento da gravação do registro[/b:e6f09fb27e]. eu trabalho assim há alguns anos, com mais de 50 usuário simultâneos só na unidade de São Paulo (há mais 18 unidades on-line pelo Brasil, então imagine quantos usuário simultâneos acessam o sistema). posso garantir que, nas condições acima descritas, a eficácia do select max será a mesma do generator.


GOSTEI 0
Lucas Guimarães

Lucas Guimarães

14/12/2006

SET GENERATOR <NOME_DO_GENERATOR> TO <VALOR>
GOSTEI 0
POSTAR