Arquivo para Generators

Generators em Firebird

Veja de uma forma bastante simplificada o uso de Generators no Interbase/Firebird.

Obter o valor de um generator

Para obter o valor de um generator devemos usar a função GEN_ID do InterBase/FireBird. A sintaxe é:

GEN_ID(NomeDoGenerator, Incremento);

Exemplos:
GEN_ID(Gen_Cliente, 1);
GEN_ID(Gen_Cliente, 0);

No primeiro exemplo o generator será incrementado e o novo valor será retornado. Já no segundo exemplo o generator não será incrementado e seu valor atual será retornado.

Dentro de um trigger podemos atribuir o valor de um generator a um campo da tabela, como mostra o exemplo a seguir:

CREATE TRIGGER TRIG_Cliente FOR Cliente BEFORE INSERT AS
BEGIN
NEW.Codigo = GEN_ID(Gen_Cliente, 1);
END^

Para obter o valor de um generator através de uma aplicação, podemos executar o comando SELECT mostrado a seguir sobre uma tabela que possua apenas um registro:

SELECT GEN_ID(NomeDoGenerator, 1) FROM NomeTabela

Onde NomeTabela é o nome de uma tabela do banco de dados que precisa ter um, e somente um, registro. Geralmente usamos a tabela de sistema RDB$DATABASE para este propósito. Eis um exemplo:

SELECT GEN_ID(Gen_Cliente_Codigo, 1) FROM RDB$DATABASE;

Reiniciar a contagem de um generator

Para re-iniciar a contagem de um generator basta executar o comando abaixo:

SET GENERATOR TO X;

Onde X é um número inteiro.

O exemplo abaixo define o valor do generator GEN_Cliente_Codigo igual a zero:

SET GENERATOR GEN_Cliente TO 0

Observação: O valor obtido com GEN_ID(GEN_Cliente, 1) após o exemplo dado anteriormente será 1 (um), pois a função GEN_ID retorna o valor do generator já incrementado.

Remover (excluir) um generator

No InterBase 6.0.x:
DELETE FROM RDB$GENERATORS
WHERE RDB$GENERATOR_NAME = ‘NOME_DO_GENERATOR’;

No FireBird:
DROP GENERATOR NOME_DO_GENERATOR;

link

Deixe um comentário

Alterar o valor de um generator

SET GENERATOR <NOME_DO_GENERATOR> TO <VALOR>

Comentários (1)

Como fazer o “drop” do generator

Não existe nenhum comando DROP GENERATOR… no InterBase/Firebird. A única possibilidade é eliminar a definição do generator da tabela de sistema:

   DELETE FROM RDB$GENERATORS
WHERE RDB$GENERATOR_NAME=’MYGEN’;

Mas este método tem algumas DESVANTAGENS:

#InterBase não verifica as dependências, o que significa que permite eliminar o Generator mesmo este estando a ser utilizado por um Trigger ou Stored Procedure.

Felizmente, basta voltar a criar o generator em falta (e definir o valor inicial para remediar o problema).
#Cada Generator consiste de duas partes:
- registo na tabela RDB$GENERATORS
- a variavel/contador em si, que é armazenado numa página especial da Base de Dados

o Campo RDB$GENERATOR_ID na Tabela RDB$GENERATORS é de factoo indice para o array de generatorsna pagina de generators.

Quando eliminamos um generator da tabela de sistema, o espaço que lhe é atribuido na página de generators(e o generator_ID) continuam não usados.

O que significa que o recem criado generator terá sempre um novo valor para rdb$generator_id em vez de reutilizar o existente.

Resumindo, eliminar o Generator vale a pena apenas se pretendermos fazer o Backup/restore da base de dado, ou se pretendermos acabar com o generator e não voltar a criar um novo.

No caso precisar de um Generator com um nome diferente , basta renomear um antigo, não utilizado:

   UPDATE RDB$GENERATORS
SET RDB$GENERATOR_NAME=’NEW_GEN’
WHERE RDB$GENERATOR_NAME=’OLD_GEN’;

Deixe um comentário

How to create generator in SP

Of course InterBase has command CREATE GENERATOR, but because it is DDL command, you can’t use it in stored procedure. But thanks to system of active tables, you can create generator by inserting it’s name directly into system table:

INSERT INTO RDB$GENERATORS (RDB$GENERATOR_NAME)
VALUES (UPPER('MYGEN'));

The new generator is available immediately, even before commit (but if you rollback, the generator-name/generator-id will be lost). Do not forget that most IB versions have bug that prevents you from creating and using too many generators.

Comentários (1)

Como alterar o valor de um Generator numa SP

Porque o comando SET GENERATOR … TO …; não é suportado dentro de Stored Procedures, a unica maneira é ler o valor actual na chamanda GEN_ID e usá-lo para ajustar o valor por outro.(mas cuidadoem ambientes multiulitizador porque estas duas chamadas GEN_ID não é garantido que serão executadas numa unica atomica operação!)

CREATE PROCEDURE SetGen (val INTEGER) AS
BEGIN
val = GEN_ID (MyGen, val – GEN_ID (MyGen,0) );
END

Deixe um comentário

How to read generator’s value in SP

Many people use 1-row table (rdb$database) to retrieve generator’s value in SP

SELECT GEN_ID(g,1) FROM rdb$database INTO :x ;

While using rdb$database table can be useful if client program needs to read generator (because you can’t “execute” standalone GEN_ID() expression from client), it is absolutely unnecessary in stored procedure. Expressions can be assigned to SP variables/parameters directly by assignment statement. E.g. procedure to retrieve next value from generator can look like:

CREATE PROCEDURE ReadGen RETURNS (ret INTEGER) AS
BEGIN
ret = GEN_ID(MyGen, 1);
END;

Deixe um comentário