IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Bases de données Delphi Discussion :

Problème avec autoincrémenté Firebird


Sujet :

Bases de données Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2002
    Messages : 247
    Par défaut Problème avec autoincrémenté Firebird
    Bonjour,

    J'ai un petit problème avec un champ autoincrémenté dans Delphi. Lorsque je veux ajouter un enregistrement, j'ai chaque fois le message d'erreur "Le champ ID doit evoir une valeur". Ce champ ID est un autoincrémenté géré par FireBird.

    J'ai créé ma base de données et ma table avec IBExpert. Dans IB expert lors de l'ajout d'un enregistrement l'autoincréménté fonctionne parfaitement par contre dans Delphi ca ne fonctionne pas.

    Voici le code pour créé la table et les autoincrémentés dans IBExperts:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    CREATE TABLE CLIENTS (
        ID INTEGER NOT NULL,
        NOM CHAR(30),
        PRENOM CHAR(30));
    alter table CLIENTS
    add constraint PK_CLIENTS
    primary key (ID);
    CREATE GENERATOR GEN_CLIENTS_ID;
    SET TERM ^ ;
     
    CREATE TRIGGER CLIENTS_BI FOR CLIENTS
    ACTIVE BEFORE INSERT POSITION 0
    AS
    BEGIN
      IF (NEW.ID IS NULL) THEN
        NEW.ID = GEN_ID(GEN_CLIENTS_ID,1);
    END
     
    ^
     
    SET TERM ; ^
     
    SET TERM ^ ;
     
    CREATE PROCEDURE SP_GEN_CLIENTS_ID
    RETURNS (ID INTEGER)
    AS
    BEGIN
      ID = GEN_ID(GEN_CLIENTS_ID, 1);
      SUSPEND;
    END
     
    ^
     
    SET TERM ; ^
    Dans Delphi, j'utilise les composants IBDatabase, IBTable et IBTransaction, DBGrid, DBNavigator et DataSource.

    Ou est le problème ?

    Merci.

  2. #2
    Membre éprouvé Avatar de lper
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    398
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2004
    Messages : 398
    Par défaut
    Salut,
    à mon avis, ton trigger n'est pas exécuté depuis Delphi (il doit y avoir un problème de sécurité ou autre au niveau de la base), à vérifier les tables RDB$TRIGGER si je me rapelle bien sur interbase.
    De plus, je trouve dangereux ton test si le ID n'est pas null, le nouveau ID ne sera pas auto-incrémenté (le test est inutile si tu voulais que tous les nouveaux enregistrements aient un ID auto-incrémenté).

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2005
    Messages : 10
    Par défaut
    moi je pense que le plus facile, c'est de créer ton generateur toi même, moi j'utilise dezign for database : datanamic. Vu que l'auto-increment n'est pas prévu pour firebird et interbase, moi je crée mon générateur voici le code que datanamic me retourne (je v prendre un exemple quelquonque parmis les tables que j'ai crée)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    CREATE TABLE LOCALITE (
        pk_localite INTEGER NOT NULL,
        localite VARCHAR(45) NOT NULL,
        codepost VARCHAR(7),
        PRIMARY KEY (pk_localite)
    );
     
    CREATE GENERATOR gen_pklocalite;
    SET GENERATOR gen_pklocalite TO 0;
     
    CREATE TRIGGER trg_localite_bi FOR LOCALITE
    BEFORE INSERT AS BEGIN
    new.pk_localite = gen_id(gen_pklocalite,1);
    END;
    Le generateur cree comme ça fonctionne parfaitement ...

    J'espère t'avoir aidé,

    Spiriteus

  4. #4
    Membre très actif
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2002
    Messages : 247
    Par défaut
    Le test ce n'est pas moi qui l'ai fait. Tout le code a été généré automatiquement par IB Experts. En fait je débute avec Firebird et j'essaye un peu de comprendre son fonctionnement.

    Qu'est-ce que je devrais modifier dans le trigger pour le rendre plus sur ?

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2005
    Messages : 10
    Par défaut
    regarde dans mon code juste au-dessus, je pense l'avoir modifié juste après que tu aies envoyé ton message, mon trigger est moins complexe et ça fonctionne ...

  6. #6
    Membre éprouvé Avatar de lper
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    398
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2004
    Messages : 398
    Par défaut
    Le premier problème est à mon avis que le trigger ne s'exécute pas depuis Delphi, il faudrait vérifier la valeur d'un flag (qui doit être à 1) dans la table système RDB$TRIGGER si tu es bien sous Interbase.

  7. #7
    Membre très actif
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2002
    Messages : 247
    Par défaut
    J'ai essayé ton trigger mais ca ne fonctionne toujours pas.



    Quand je clique sur le "+" pour insérer un enregistrement, la ligne apparait bien mais le champ PK_LOCALITE reste vide.

    Quand je cliquer sur le "v", le message d'erreur s'affiche.

    Pour la table RDB$TRIGGERS, je ne sais pas ou il faut aller la chercher.

  8. #8
    Membre éprouvé Avatar de lper
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    398
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2004
    Messages : 398
    Par défaut
    C'est dans les tables systèmes de ta base, j'ai revu un bug du style :
    Bug fix release of IBDataWorks 1.2.4 available for download
    May. 31, 2004
    This is bug fix release of IBDataWorks 1.2.4, containing the following fixes:

    Added custom gds32.dll to handle new Firebird client library (fbclient.dll).
    Fixed bug in reverse engineering where Stored Procedures were not extracted when RDB$System_Flag is NULL .

    Je crois que pour les triggers, y avait le même problème, il faut mettre à 1 le RDB$SYSTEM_Flag de la table RDB$TRIGGERS.

  9. #9
    Membre très actif
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2002
    Messages : 247
    Par défaut
    Ca ne marche pas, je n'ai pas le droit de modifier le flag.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Error Message:
    ----------------------------------------
    Unsuccessful execution caused by system error that does not preclude successful execution of subsequent statements.
    action cancelled by trigger (0) to preserve data integrity.
    cannot modify or erase a system trigger

  10. #10
    Membre confirmé

    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 142
    Par défaut
    Salut,

    Comment utilises-tu ta procédure stockée ?

    1) Pourquoi n'utilises-tu pas un IBQuery relié à un IBUpdateSQL ou un TIBDataSet ?
    Avec ces composants tu as à ta disposition la propriété GeneratorField (depuis Delphi 6, je crois) qui permet de définir ton générateur.

    2) J'utilise le même type de Gen et de Trigger que ceux donnés par Spiriteus. Ca ne doit pas poser de problème de ce côté là.

    3) Par acquis de conscience, tu peux aussi regarder la table RDB$GENERATORS pour voir si ton générateur est bien déclaré.

  11. #11
    Membre Expert

    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Janvier 2004
    Messages
    2 123
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 123
    Par défaut
    Salut,

    Quelques questions à tout hasard...
    Quel est ta version de FireBird ? Le dialecte utilisé ?

  12. #12
    Membre très actif
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2002
    Messages : 247
    Par défaut
    J'utilise Firebird 1.5.2
    J'utilise le Dialect 1
    et Delphi 5 Pro

    Le tout sous Win98 SE

  13. #13
    Membre Expert

    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Janvier 2004
    Messages
    2 123
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 123
    Par défaut
    Alors j'ai une bonne nouvelle pour toi

    FireBird 1.5.x ne fonctionne qu'avec le Dialecte 3.

  14. #14
    Membre très actif
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2002
    Messages : 247
    Par défaut
    OK Merci, je teste ca tout de suite.

  15. #15
    Membre très actif
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2002
    Messages : 247
    Par défaut
    J'ai essaye avec le Dialecte 3 mais le champ autoincrémenté ne fonctionne toujours pas. L champ est toujours vide dans la grille de Delphi

    Pourtant j'ai bien un trigger sur BEFORE INSERT qui appelle mon generateur.

  16. #16
    Membre Expert

    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Janvier 2004
    Messages
    2 123
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 123
    Par défaut
    Je pense avoir trouver...

    Sous Delphi, il faut lancer la PS (si je me souviens bien)

    donc un truc du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
     
    var
      iPKClt : integer;
      sSQL : string;
    begin
    ....
        try
            IBTrans.StartTransaction; // IBTrans : TIBTransaction
     
            IBPS.StoredProcName := 'SP_GEN_CLIENTS_ID'; //IBPS : TIBStoredProc
            IBPS.ExecProc;
            iPKClt := IBPS.Params[0].AsInteger;
            IBPS.Close;
     
            with IBSQL1 do begin // IBSQL1 : TIBSQL
     
                sSQL := .... 
    // La requete d'insertion avec devant chaque paramètre variable le caractère ':'
     
                SQL.Clear;
                SQL.Add(sSQL);
     
                Params[0].AsInteger := iPKClt;
                .....
     
                Prepare;
     
                ExecQuery;
            end;
            IBTrans.Commit;
        except
            IBTrans.RollBack;
        end;
        IBSQL1.Close;
    end;
    A+

  17. #17
    Membre éprouvé Avatar de lper
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    398
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2004
    Messages : 398
    Par défaut
    Citation Envoyé par yobenzen
    Je pense avoir trouver...

    Sous Delphi, il faut lancer la PS (si je me souviens bien)
    Je ne comprend pas pourquoi on parle de procédure stockée dans ce cas, le trigger est seul pour initialiser le champs autoincrémenté.
    Peux tu vraiment vérifier que c'est bien le trigger qui ne s'execute pas en initialisant le champs dans Delphi avant l'insert.

  18. #18
    Membre éclairé
    Inscrit en
    Juin 2002
    Messages
    409
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 409
    Par défaut
    Bonjour, j'ai le meme souci que notre ami cd090580 :
    Toutes mes tables ont une cle primaire not null de type integer auto-incrementee.
    Et le generateur n'est pas pris en compte dans delphi puisqu'il s'execute apres seulement l'envoi de la requete par le DataSetProvider a la BD.
    Pour resoudre ce probleme, je n'ai pas trouve mieux que de passer par des procedures stockees qui se charge d'inserer le nouvel enregistrement avec la bonne PK grace a un generator. (exactement comme l'a decrit yobenzen je croit)

    Mais, maintenant que je maitrise un peu mieux tous ca, je pense a une autre chose : C'est le DataSetProvider qui te bloque parcequ'il voit a juste titre que le champ PK est absolument requis ! Donc essaye voir de modifier la proriete REQUIRED du champ PK de ta TTable ou SQLTable auquel le DSP est lie. (cela suppose bien sur que tu utilise des champs statiques !)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème avec Rave et Firebird
    Par Tcheby dans le forum Bases de données
    Réponses: 19
    Dernier message: 29/01/2011, 10h30
  2. [JPOX]Problèmes avec un identifiant autoincrement
    Par Vikisme dans le forum Persistance des données
    Réponses: 1
    Dernier message: 29/05/2007, 15h44
  3. Problème avec le driver ODBC IBPhoenix Firebird/Interbase
    Par lio33 dans le forum Connexion aux bases de données
    Réponses: 5
    Dernier message: 27/02/2006, 09h59
  4. Réponses: 2
    Dernier message: 21/07/2005, 12h05
  5. Problème avec la librairie rfunc sous Firebird
    Par yayelix dans le forum SQL
    Réponses: 4
    Dernier message: 17/05/2005, 16h49

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo