Generator ou autre

sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 - 8 oct. 2012 à 18:04
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 - 9 oct. 2012 à 22:21
Bonjour,

Je ne suis pas sûr de poster au bon endroit, mais j'ai fait une petite recherche dans la partie "SQL" de ce site et il ne m'a pas l'air d'y avoir grand chose...

Ma question :
J'ai une table (firebird) avec une clé primaire (NUM_ELEMENT, NUM_CLIENT). NUM_CLIENT est récupéré à partir d'une autre table. Je voudrais que le NUM_ELEMENT soit autoincrémenté, mais pour un client. C'est à dire, que si j'ai un client A et un client B, que j'ai les éléments 1, 2, 3 et 4 pour le A, et 1 et 2 pour le B, quand j'insère un nouvel enregistrement pour B, je voudrais qu'il prenne le n°3. Je sais coder ça en delphi, mais je me demandais s'il existait une façon de coder ça en trigger avec un générator ou un truc du genre. Pour le moment, je n'arrive pas à indiquer à mon générator qu'il faut que cette incrémentation soit conditionnée...

Une idée ?


Simon

5 réponses

beckerich Messages postés 302 Date d'inscription jeudi 29 septembre 2005 Statut Membre Dernière intervention 17 septembre 2013 2
8 oct. 2012 à 23:34
bonsoir,

si j'ai bien compris, l'idée serait de créer un générator dynamiquement pour chaque nouveau client, puis de récupérer l'id quand c'est nécessaire.
J'utilise Zeos pour mes accès à Firebird. Il existe un objet TZSequence dans cette bibliothèque. J'ai fait un objet autour de TZSequence :

unit dbm_sequence;

interface

uses
  ZConnection, ZSequence, Classes, dbm_connection;

type
  TSerialGP =  (gpsDocIn, gpsMemo, gpsDocCli, gpsWSer);
  TDBM_sequence = class(TZSequence)
  public
    constructor Create(AOwner: TComponent; Connection: TDBM_connection); reintroduce; overload;
    function SerialByName(s_gen: string): integer;
    function Serial(gps_gen: TSerialGP): integer;
    function Get(gps_gen: TSerialGP): integer;
  end;

const
  AS_GEN: array[TSerialGP] of string = (
                                       'GEN_DIN'    // document entrant
                                      ,'GEN_MEMO'   // notes et mémos
                                      ,'GEN_DOCCLI' // documents clients traités
                                      ,'GEN_WSER'   // sérial générique
                                      );

implementation

uses
  SysUtils;

{ TGPZSequence }

constructor TDBM_sequence.Create(AOwner: TComponent; Connection: TDBM_connection);
begin
  inherited Create(AOwner);
  Self.Connection := Connection.getConnection;
end;

function TDBM_sequence.Get(gps_gen: TSerialGP): integer;
begin
  Result := Serial(gps_gen);
end;

function TDBM_sequence.Serial(gps_gen: TSerialGP): integer;
begin
  SequenceName := UpperCase(AS_GEN[gps_gen]);
  Result       := GetNextValue;
  Assert(Result > 0);
end;

function TDBM_sequence.SerialByName(s_gen: string): integer;
begin
  SequenceName := UpperCase(s_gen);
  Result       := GetNextValue;
  Assert(Result > 0);
end;

end.


Tu pourrais t'en inspirer selon la bibliothèque que tu utilises.
Il faudrait ajouter une méthode du genre :

procedure addGenerator(const codeClient: string);
qui créerait le generator du client.
Quand tu as besoin d'une valeur, tu crées une instance de TDBM_sequence et tu récupères la valeur par instance.SerialByName(codeClient)

Enfin, quelque chose comme cela, si cela peux t'aider.

Le code de TDBM_connection :
unit dbm_object;

interface

uses
  ZConnection;

type
  TDBM_object = class(TObject)
  protected
    connection: TZConnection;
  public
    constructor Create(connection: TZConnection); virtual;
    destructor Destroy; override;
    function getConnection: TZConnection;
  end;

implementation

{ TDBM_object }

constructor TDBM_object.Create(connection: TZConnection);
begin
  Self.connection := connection;
end;

destructor TDBM_object.Destroy;
begin

  inherited;
end;

function TDBM_object.getConnection: TZConnection;
begin
  Result := connection;
end;

end.



unit dbm_connection;

interface

uses
  dbm_object, ZConnection;

type
  TDBM_connection = class(TDBM_object)
  private
    _connection: TZConnection;
  public
    constructor Create(connection: TZConnection);
    procedure startTransaction;
    procedure commit;
    procedure rollback;
    function  inTransaction: boolean;
    function  connected: boolean;
    procedure connect;
    procedure disconnect;
    function getConnection: TZConnection;
  end;

implementation

{ TDBM_connection }

procedure TDBM_connection.commit;
begin
  if inTransaction then
    getConnection.Commit;
end;

procedure TDBM_connection.connect;
begin
  if not connected then
    getConnection.Connect;
end;

function TDBM_connection.connected: boolean;
begin
  Result := getConnection.Connected;
end;

constructor TDBM_connection.Create(connection: TZConnection);
begin
  _connection := connection;
end;

procedure TDBM_connection.disconnect;
begin
  if connected then
    getConnection.Disconnect;
end;

function TDBM_connection.getConnection: TZConnection;
begin
  Result := _connection;
end;

function TDBM_connection.inTransaction: boolean;
begin
  Result := getConnection.InTransaction;
end;

procedure TDBM_connection.rollback;
begin
  if inTransaction then
    getConnection.Rollback;
end;

procedure TDBM_connection.startTransaction;
begin
  if not inTransaction then
    getConnection.StartTransaction;
end;

end.


Luc.
0
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 15
9 oct. 2012 à 09:50
Merci Luc,

De bonnes idées, je note.

En revanche, je préfèrerais le gérer au moyen d'une procedure stockée, trigger ou autre moyen embarqué dans la base.


Simon
0
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
9 oct. 2012 à 15:12
Bonjour,
tu as une relation 1-N entre la table CLIENTS et
ENREGISTREMENTS ce qui se traduit dans ta base
par deux clés primaires, deux generators, deux triggers et une contrainte sur la foreign keys de ENREGISTREMENTS.
lors de l'insertion dans enregistrements, il suffit de caler le CLIENT et son code s'introduit automatiquement dans la table et le generator incrémente automatiquement la clé de ENREGISTREMENTS.

cantador
0
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 15
9 oct. 2012 à 15:29
Salut Cantador,

Qu'entends tu par "caler le CLIENT" ?


Simon
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
9 oct. 2012 à 22:21
"caler le CLIENT" :

- soit par code
- soit appliquer un locate sur la table client
- soit afficher le client dans un formulaire avec champ db

tout dépend du contexte que je ne connais pas..

cantador
0
Rejoignez-nous