AUTO INCREMENT FIREBIRD

Firebird

09/12/2013

Galera boa noite bem eu fiz um generate auto_increment no IBExpert mais infelizmente ele não está gerando o ID e fica como NULL.
Raniel Gomes

Raniel Gomes

Curtidas 0

Respostas

Joel Rodrigues

Joel Rodrigues

09/12/2013

Movendo para a sala de Firebird.
GOSTEI 0
Joel Rodrigues

Joel Rodrigues

09/12/2013

Você criou o generator e o trigger?
GOSTEI 0
Raniel Gomes

Raniel Gomes

09/12/2013

Não criei o Trigger como faz?
GOSTEI 0
Deivison Melo

Deivison Melo

09/12/2013

Você poderá fazer uso dos generator´s

CREATE GENERATOR AGenerator;

SET GENERATOR AGenerator TO 1;


A função: "GEN_ID" é usada para incrementar valores ao seu generator...

Veja o exemplo abaixo:

  SELECT GEN_ID(AGenerator, 1) from RDB$DATABASE;




Abaixo mostrarei como criar um Generator e Popular o mesmo com uso de uma
trigger.


CREATE GENERATOR CUST_NO_GEN;

SET GENERATOR CUST_NO_GEN TO 0;





SET SQL DIALECT 3;

CREATE GENERATOR CUST_NO_GEN;

SET TERM ^ ;



CREATE OR ALTER TRIGGER SET_CUST_NO FOR CUSTOMER
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
    if (new.cust_no is null) then
    new.cust_no = gen_id(cust_no_gen, 1);
END
^


SET TERM ; ^



Além dos Generators você poderá fazer uso das sequences
adicionadas ao firebird em sua versão 2.0.

A explicação das mesmas ficará para uma outra oportunidade
ou no caso de você preferir o uso delas, basta sinalizar
que exemplificarei a sua criação e uso.

Abração e bons códigos.

Emanoel Deivison
Recife - PE
GOSTEI 0
Thiago Irrazabal

Thiago Irrazabal

09/12/2013

Boa tarde, só para "opinar" porque acredito que tua dúvida já foi sanada pelo nosso colega Deivison, enfim... eu não uso trigger's para incrementar os generators porque acho que fica muita "sujeira" no banco, explicando: para cada tabela que tu tem tu tem um(ou mais) generator, e para cada um teria uma trigger, então ficaria cheia de trigger's no teu banco só para incremento. Eu faço o incremento do generator pela aplicação mesmo. Abraço




Att,
Thiago Irrazabal de Oliveira.
GOSTEI 0
Raniel Gomes

Raniel Gomes

09/12/2013

Como seria sem usar trigger.
GOSTEI 0
Joel Rodrigues

Joel Rodrigues

09/12/2013

Como seria sem usar trigger.
Como ele disse, e o que dá para imaginar, é que ele incrementa esse campo pela aplicação. É mais uma forma de se fazer, assim como quase tudo na programação. Eu, particularmente, acho interessante transferir essa responsabilidade para o banco, por julgar mais seguro.
Abraço a todos.
GOSTEI 0
Deivison Melo

Deivison Melo

09/12/2013

Veja outro exemplo feito dentro do delphi:

function GeneratorID (aName: string; Connection: TSQLConnection;
  Incrementa: Boolean): integer;
var
  Qry: TSQLQuery;
begin
  Qry := TSQLQuery.Create(nil);
  try
    Qry.SQLConnection := Connection;
    if Incrementa then
      Qry.SQL.Add(
        'SELECT GEN_ID('+aName+', 1) FROM RDB$DATABASE')
    else
      Qry.SQL.Add(
        'SELECT GEN_ID('+aName+', 0) FROM RDB$DATABASE');
    Qry.Open;
    Result := Qry.Fields[0].AsInteger;
  finally
    FreeAndNil(Qry);
  end;
end;




PS. Lembrando que usei os componentes DBX.

Abração e bons códigos!

Atenciosamente,

Emanoel Deivison
Recife - PE
GOSTEI 0
Thiago Irrazabal

Thiago Irrazabal

09/12/2013

Bom dia, eu uso assim

function IncrementaPK(NomeGenerator_Tabela: string; i: Integer;
  CampoIncremento: string): Integer;
var
  x, Generator: string;
  Q1, Q2, Q3: TSQLQuery;
const
  sSqlFindGenerator = 'SELECT RDB$GENERATOR_NAME AS GEN FROM RDB$GENERATORS WHERE UPPER(RDB$GENERATOR_NAME) = ''%s''';
  sSqlGetGenerator = 'SELECT GEN_ID(%s,%s) AS INC FROM RDB$DATABASE';
  sSqlMaxField = 'SELECT COALESCE(MAX(%s),0) AS MAXFIELD FROM %s';
  sSqlSetGenerator = 'SET GENERATOR %s TO %s';
begin
  Generator := UpperCase('G_' + NomeGenerator_Tabela);
  Generator := Copy(Generator, 1, 31);
  Q1 := ExecSql(Format(sSqlFindGenerator, [Generator]));
  try
    if Q1.FieldByName('GEN').IsNull then
      begin
        Connection.ExecuteDirect(' CREATE GENERATOR ' + Generator);
        x := Format(sSqlMaxField, [CampoIncremento, NomeGenerator_Tabela]);
        if Trim(CampoIncremento) <> '' then
          begin
            if Existe_Tabela(UpperCase(NomeGenerator_Tabela)) then
              begin
                Q2 := ExecSql(x);
                try
                  Connection.ExecuteDirect(Format(sSqlSetGenerator, [Generator, Q2.FieldByName('MAXFIELD').AsString]));
                finally
                  FreeAndNil(Q2);
                end;
              end;
          end;
      end;
  finally
    FreeAndNil(Q1);
  end;
  Q3 := ExecSql(Format(sSqlGetGenerator, [Generator, IntToStr(i)]));
  try
    Result := Q3.FieldByName('INC').AsInteger;
  finally
    FreeAndNil(Q3);
  end;
end;



Nesse caso precisa dessa outra função.

function ExecSql(X: String): TSQLQuery;
begin
  Result := TSQLQuery.Create(nil);
  Result.SQLConnection := Connection;
  Result.Close;
  Result.SQL.Clear;
  Result.SQL.Add(X);
  Result.Open;
end;





Att,
Thiago Irrazabal de Oliveira.
GOSTEI 0
Marcelino Wille

Marcelino Wille

09/12/2013

Obrigado pela dica.
Sou iniciante em programação comecei estudando delphi, mas resolvi migrar para o LAZARUS essa dica foi perfeita
function Tdm.GeneratorID(aName: string; Connection: TIBConnection;
  Incrementa: Boolean): integer;
var
  Qry: TSQLQuery;
begin
  Qry := TSQLQuery.Create(nil);
  try
    Qry.DataBase := Connection;
    if Incrementa then
      Qry.SQL.Add(
        'SELECT GEN_ID('+aName+', 1) FROM RDB$DATABASE')
    else
      Qry.SQL.Add(
        'SELECT GEN_ID('+aName+', 0) FROM RDB$DATABASE');
    Qry.Open;
    Result := Qry.Fields[0].AsInteger;
  finally
    FreeAndNil(Qry);
  end;

end;                                   

como usei
procedure Tdm.SQLFUNCIONARIONewRecord(DataSet: TDataSet);
begin
     SQLFUNCIONARIO.FieldByName('COD_FUNCIONARIO').Value:=GeneratorID('GEN_FUNCIONARIO_ID',dbtransportes,TRUE);
end;                              
GOSTEI 0
Denilosn Carlos

Denilosn Carlos

09/12/2013

function Tdm.GeneratorID(aName: string; Connection: TIBConnection;
Incrementa: Boolean): integer;
var
Qry: TSQLQuery;
begin
Qry := TSQLQuery.Create(nil);
try
Qry.DataBase := Connection;
if Incrementa then
Qry.SQL.Add(
'SELECT GEN_ID('+aName+', 1) FROM RDB$DATABASE')
else
Qry.SQL.Add(
'SELECT GEN_ID('+aName+', 0) FROM RDB$DATABASE');
Qry.Open;
Result := Qry.Fields[0].AsInteger;
finally
FreeAndNil(Qry);
end;

end;


este código eu uso em todas as tabelas ?
GOSTEI 0
Denilosn Carlos

Denilosn Carlos

09/12/2013

Por exemplo tenho cadastro de usuário, cadastro de fornecedor, cadastro de cliente


o código é o mesmo para gerar ?
GOSTEI 0
POSTAR