Fórum FB não retorna ID gerada #345672
08/09/2007
0
Estou desenvolvendo um projeto com D7+DBExpress/FB2.0. No BD criei triggers e generators para os campos auto-incremento de ID das tabelas.
Está tudo funcionando bem, porém qdo se adiciona um novo registro, este é gravado perfeitamente, porém o valor do ID (gerado pelo BD) não retorna, não aparece no componente datawhare. Mesmo fazendo o controle de transações.
Para poder ver o valor criado, somente fechando e abrindo novamente o CDS. Há outra solução?
Abraço.
Luciano.badoe
Curtir tópico
+ 0Posts
09/09/2007
Raserafim
então você tem a opção de atualiar o ClientDataSet (quase o mesmo que abrir e fechar.
uma outra opção (que é a que eu utilio) é não colocar o autoincremento no banco de dados, criar apenas o gerador.
ex:
select gen_id(GEN_CLIENTES_ID, 1) as ID from RDB$DATABASE
no delphi vc utilia uma query que vai ter uma instrução que vai pegar este valor e automaticamente incrementar um.
então vc coloca este valor no campo do ClientDataSet e depois da o commint.
Gostei + 0
09/09/2007
Luciano.badoe
Vou tentar, obrigado pela ajuda.
Gostei + 0
10/09/2007
Robson Fernandes
Fiquem à vontade para modificar.
{
***************************************************************************************
Componente zFBTable
By Robson Fernandes - 2007
10/09/2007
robson.fernandes@gmail.com
Para trabalhar com Generators e inserir o valor no campo (geralmente ID de tabelas) em bancos
Firebird / Interbase.
Propriedades adicionadas:
IdFieldName: O nome do campo ID (Para se autoincremento)
Generator: O nome do generator. Se o generator não existir, é criado um com o nome
especificado e ajustado para o número máximo do campo ID
Obs: Diferentemente de triggers (que vc tem q criar para cada tabela), esse componente
se baseia no generator e adiciona no campo de ID.
O bom disto é que não é necessário ficar dando refresh na tabela para retornar o ID
para o campo, sem se falar que poupa o trabalho de ter que ficar criando triggers e generators.
Se for deixada em branco a propriedade Generator e forem ajustadas as propriedades
de TableName e IdFieldName, o componente automaticamente sugere o nome de um generator. Se
quiser utilizar, basta deixar do jeito que está. Se existir, o componente o utiliza. Senão,
é criado o generator com o número máximo do campo especificado.
Espero que este componente agilize a vida de muitos programadores por aí, às turras com generators, triggers :P
***************************************************************************************
}
unit zFBtable;
interface
uses
SysUtils, Classes, DB, ZAbstractDataset, ZAbstractRODataset,
ZAbstractTable, ZDataset, StdCtrls;
type
tzFBtable = class(TZTable)
private
FIdFieldName: string;
FGenerator: string;
procedure SetGenerator(const Value: string);
procedure SetIdFieldName(const Value: string);
protected
procedure DoBeforePost; Override;
public
Constructor Create(AnOwner:TComponent); Override;
Destructor Destroy; Override;
published
property IdFieldName: string read FIdFieldName write SetIdFieldName;
property Generator: string read FGenerator write SetGenerator;
end;
procedure Register;
implementation
Constructor tzFBtable.Create(AnOwner:TComponent);
begin
inherited Create(AnOwner);
end;
Destructor tzFBtable.Destroy;
begin
inherited Destroy;
end;
procedure Register;
begin
RegisterComponents(´Zeos Access´, [tzFBtable]);
end;
{ tzFBtable }
procedure tzFBtable.DoBeforePost;
var vFlagVazio: Boolean;
vMaxId: Integer;
begin
inherited;
if Self.State <> dsInsert then
exit;
if (Trim(FIdFieldName)=´´) then
exit;
if (Trim(FGenerator)=´´) then
exit;
if (Self.Connection = nil) then
exit;
with TZQuery.Create(nil) do
try
Connection := Self.Connection;
// Verifica se existe o Generator.
Sql.Add(´select RDB$GENERATOR_NAME from RDB$GENERATORS where RDB$GENERATOR_NAME = :NOME_GENERATOR´);
ParamByName(´NOME_GENERATOR´).AsString := FGenerator;
Open;
vFlagVazio := IsEmpty;
Close;
if vFlagVazio then
begin
// Se não existir o generator, crio e atribuo o Max do Campo id como o valor dele
Sql.Clear;
Sql.Add(´select max(´ + FIdFieldName + ´) as MaxId from ´ + Self.TableName);
Open;
vMaxId := FieldByName(´MaxId´).AsInteger;
Close;
Sql.Clear;
Sql.Add(´CREATE GENERATOR ´ + FGenerator);
ExecSql;
Sql.Clear;
Sql.Add(´SET GENERATOR ´ + FGenerator + ´ TO ´ + IntToStr(vMaxId));
ExecSql;
end;
Sql.Clear;
Sql.Add(Format(´select gen_id(¬s, 1) as ID from RDB$DATABASE´,[FGenerator]));
Open;
Self.FieldByName(FIdFieldName).AsInteger := FieldByName(´ID´).AsInteger;
Close;
finally
Free;
end;
end;
procedure tzFBtable.SetGenerator(const Value: string);
begin
FGenerator := Value;
end;
procedure tzFBtable.SetIdFieldName(const Value: string);
begin
FIdFieldName := Value;
if (Trim(FGenerator)=´´) then
Generator := ´GEN_´ + UpperCase(Value) + ´_´ + UpperCase(Self.TableName);
end;
end.
Gostei + 0
10/09/2007
Raserafim
não testei o componente, mas pelo que percei da descerição o que ele fa é automatizar justamente a idéia que eu sugeri. parabéns
Gostei + 0
10/09/2007
Martins
Bons códigos.
Gostei + 0
11/09/2007
Robson Fernandes
O Componente é descendente de um TZTable.
Vlw galera !
Gostei + 0
07/01/2008
Vagner.oliveira
Tenho o ZeosLib instalado e Delphi 7
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)