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 :

[IB][IBQUERY][D7 pro] Création de Triggers à la volée.


Sujet :

Bases de données Delphi

  1. #1
    Expert confirmé
    Avatar de N1bus
    Homme Profil pro
    Dev. Web & OpenERP
    Inscrit en
    Janvier 2003
    Messages
    2 827
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Dev. Web & OpenERP
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2003
    Messages : 2 827
    Points : 5 673
    Points
    5 673
    Par défaut [IB][IBQUERY][D7 pro] Création de Triggers à la volée.
    Bonjour,

    Dans mon application, j'ai créé une fonction qui recrée dynamiquement la base de données et les tables si la base est absente au démarrage du programme. (Ceci est le cas pour la première utilisation du programme).

    Je souhaite également créer "à la volée" les GENERATORS pour créer un champ autoincrement .(Pas de problème).

    Evidemment, je souhaite créer à la volée les TRIGGERS.
    J'ai parcouru les Faqs, les tutos,les docs, les *.hlp et autres; j'ai également lu le tuto sur les compteurs autoincrémentés (sur ce site).

    J'ai toujours une erreur. La réponse est une erreur de syntaxe SQL à telle ligne...

    Voici le code de cette fonction dans Delphi :
    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
     
    //Créations des triggers ===============================
     1> Function TMain.CreateTrigInc(NomGen : string; NomTable : string):String;
     2> var S : string;
     3> begin
     4> S :=   'SET TERM ^;'+
     5>          'CREATE TRIGGER CREATE_ID FOR ' + NomTable +'  '+
     6>          'BEFORE INSERT POSITION 0  '+
     7>          'AS BEGIN  '+
     8>          'NEW.ID = GEN_ID('+ NomGen +', 1);  '+
     9>          'END ^
    10>         'SET TERM ;^';
    11> Result := S;
    12> end;
    //-----------------------------------------------------
    Plus loin dans le code, l'appel à cette fonction dans Delphi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    IBQuery.SQL.Clear;
    IBQuery.SQL.Add(CreateTrigInc('GEN_ID_AP','AP'));
    IBQuery.ExecSQL;
    La fonction retourne une erreur de syntaxe .
    Notes :
    - Les N° de lignes (xx>) sont ici pour la compréhension...
    - La requete SQL est effectuée au cours d'une TRANSACTION (IBTransaction.Commit;except >IBTransaction.Rollback
    - La BD (IB6 GPL) est CONNECTED
    - SQLDialect = 3
    - J'utilise le
    Quinté gagnant ?? : TIBDataBase =>TIBTransaction => TIBQuery => TIBUpdateSQL => TDataSource
    - Les instructions SQL et TRANSACTIONS sont éxécutées correctement ailleurs dans le code.
    - Je n'ai pas mis la fonction pour créer les GENERATORS dans ce post, mais elle fonctionne (vérifié avec IBConsole)
    - La requete doit être exécutée pour les 40 tables
    - Je n'ai pas vérifié si le TRIGGER fonctionne correctement, le but, pour l'instant est d'envoyer la requête correctement.

    Or, la requête ne retourne aucune erreur si elle exécutée depuis la fenetre SQL de IBConsole
    Dans ce cas, le code est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    1> SET TERM ^;
    2> CREATE TRIGGER CREATE_ID FOR AP
    3> BEFORE INSERT POSITION 0
    4> AS
    5> BEGIN
    6> NEW.ID = GEN_ID(GEN_ID_AP, 1);
    7> END^
    8> SET TERM ;^
    J'ai probablement un problème de syntaxe dans le IBQuery...
    D'avance je remercie les développeurs qui pourront me dire où est l'erreur, oubien quelle technique dois-je employer. Et merci aux développeurs de me confirmer si l'utilisation du Quinté gagnant est une bonne combinaison de composants à utiliser.

    Cordialement
    N1bus

  2. #2
    Expert confirmé
    Avatar de N1bus
    Homme Profil pro
    Dev. Web & OpenERP
    Inscrit en
    Janvier 2003
    Messages
    2 827
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Dev. Web & OpenERP
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2003
    Messages : 2 827
    Points : 5 673
    Points
    5 673
    Par défaut
    Euréka !

    Pour ceux que cela interresse j'ai réussi à faire passer la requête sans spécifier SET TERM ^ au debut
    mais en passant les ; (semicolon) avec Chr(59) .

    Voici le code qui fonctionne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    //Créations des triggers ========================================
    Function TMain.CreateTrigInc(NomGen : string; NomTable : string):String;
    1> var S : string;
    2> begin
    3> S :=   'CREATE TRIGGER CREATE_ID FOR ' + NomTable +'  '+ chr(13) +
    4> 'BEFORE INSERT POSITION 0 '+ chr(13) +
    5> 'AS BEGIN  '+ chr(13) +
    6> 'NEW.ID = GEN_ID('+ NomGen +', 1)' + chr(59)+ chr(13) +
    7> 'END'+ chr(59) ;
    8> Result := S;
    9> end;
    //---------------------------------------------------------------
    Rappel :
    In SQL statements passed to DSQL, omit the terminating semicolon. In embedded applications written in C and C++, and in isql, the semicolon is a terminating symbol for the statement, so it must be included.
    //
    Because each statement in a stored procedure body must be terminated by a semicolon, you must define a different symbol to terminate the CREATE TRIGGER in isql. Use SET TERM before CREATE TRIGGER to specify a terminator other than a semicolon. After CREATE TRIGGER, include another SET TERM to change the terminator back to a semicolon.
    Donc, il semblerait que cela s'applique lorsque qu'on effectue la requete depuis la fenetre ISQL (InteractiveSQL) de IBConsole (Dans le menu TOOLS)
    Qu'il est bon de le savoir...

    N1bus

  3. #3
    Membre du Club
    Inscrit en
    Septembre 2004
    Messages
    62
    Détails du profil
    Informations forums :
    Inscription : Septembre 2004
    Messages : 62
    Points : 59
    Points
    59
    Par défaut
    Merci de faire profiter de ton expérience. En effet, cette remarque risque d'être très utile, en tout cas, elle l'est déjà pour moi. Il peut paraître évident pour les autres membres du club que tu nous donne ta solution, mais un petit mot de remerciement fait toujours plaisir et encourage à apporter d'autres aides.
    Merci et bonne programmation à tous!

  4. #4
    Expert confirmé
    Avatar de N1bus
    Homme Profil pro
    Dev. Web & OpenERP
    Inscrit en
    Janvier 2003
    Messages
    2 827
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Dev. Web & OpenERP
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2003
    Messages : 2 827
    Points : 5 673
    Points
    5 673
    Par défaut
    Ben ça c'est cool

    N1bus

  5. #5
    Membre expert
    Avatar de Barbibulle
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    2 048
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 2 048
    Points : 3 342
    Points
    3 342
    Par défaut
    Citation Envoyé par N1bus
    Euréka !

    Pour ceux que cela interresse j'ai réussi à faire passer la requête sans spécifier SET TERM ^ au debut
    mais en passant les ; (semicolon) avec Chr(59) .
    Pourquoi n'avez vous pas tout simplement essayé le ; à la place du chr(59) ? Le résultat sera le même pour la simple raison que chr(59) et ';' sont identiques... Donc dans votre chaine S que vous y metiez un ';' ou un chr(59) c'est strictement la même chose.

    Si votre code c'est mis à marché c'est surtout parce que vous avez enlever le 'SET term ^;' de votre chaine.

    Le TIBQuery s'attend a avoir un et un seul ordre SQL, et envoie à interbase la chaine SQL en lui précisant que c'est un et un seul ordre SQL. De ce fait le changement de term est innutile.

    Remarque 2 (Pour chipoter car l'écart en terme de performance et resource utilisé doit pas être grand):
    Pour ce genre de commande SQL (CREATE etc..) qui ne renvoient pas de données (à contrario du SELECT) vous pouvez utiliser le TIBSQL à la place de votre TIBQuery.
    Le TIBSQL est plus leger, plus rapide et donc plus adapté à ce genre d'ordre SQL.

    Et enfin pour information il y a un moyen plus facile et rapide pour créer une base de données. Simplement faire un restaure de la sauvegarde d'une base vide, c'est plus rapide en exécution et en temps de développement (quelques lignes de code avec le TIBRestoreService).

    Et pour conclure : Merci d'avoir posté votre solution à votre probleme, celà sera certainement utile à d'autres qui se poseraient la même question.

  6. #6
    Expert confirmé
    Avatar de N1bus
    Homme Profil pro
    Dev. Web & OpenERP
    Inscrit en
    Janvier 2003
    Messages
    2 827
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Dev. Web & OpenERP
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2003
    Messages : 2 827
    Points : 5 673
    Points
    5 673
    Par défaut
    Citation Envoyé par :idea: Barbibule
    Et enfin pour information il y a un moyen plus facile et rapide pour créer une base de données. Simplement faire un restaure de la sauvegarde d'une base vide, c'est plus rapide en exécution et en temps de développement (quelques lignes de code avec le TIBRestoreService).
    Oui, je sais mais cela m'assure l'existence de la base et cela même si l'utilisateur a supprimé le fichier par erreur.

    Et pis, c'était aussi un peu pour le sport :
    cela me permet d'approfondir mes connaissances.
    (J'ai encore assez de jus pour écrire quelques lignes de code )

    Pour le ; et chr(59) :
    Vous avez raison.

    J'ai tellement cherché à savoir pouquoi mon IBQUERY ne voulait pas me passer la requête que j'avais pensé qu'il fallait l'empêcher de s'exécuter
    , un peu à la manière d'un
    en PHP qui va AFFICHER ; et ne va pas l'interpréter.

    Comme quoi, on s'égare parfois .... Faudrait que je laisse reposer mon neurone....
    Merci quand même pour les conseils

    Cordialement
    N1bus

  7. #7
    Membre expert
    Avatar de Barbibulle
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    2 048
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 2 048
    Points : 3 342
    Points
    3 342
    Par défaut
    Citation Envoyé par N1bus
    Citation Envoyé par :idea: Barbibule
    Et enfin pour information il y a un moyen plus facile et rapide pour créer une base de données. Simplement faire un restaure de la sauvegarde d'une base vide, c'est plus rapide en exécution et en temps de développement (quelques lignes de code avec le TIBRestoreService).
    Oui, je sais mais cela m'assure l'existence de la base et cela même si l'utilisateur a supprimé le fichier par erreur.
    L'une ou l'autre des méthodes est strictement identique du point de vue du résultat optenu. Lorsque l'on fait une restauration d'une base à partir d'un backup, on peux le faire sur une base existante ou créer une nouvelle base. Et donc cette dernière fonctionnalité qui peut être utile pour créer la base la première fois (première installation) ou si la base a été effacée.

    Citation Envoyé par N1bus
    Et pis, c'était aussi un peu pour le sport :
    cela me permet d'approfondir mes connaissances.
    (J'ai encore assez de jus pour écrire quelques lignes de code
    Le seul problème c'est que l'informatique n'est pas encore une discipline olympique .

    Citation Envoyé par N1bus
    Pour le ; et chr(59) :
    Vous avez raison.

    J'ai tellement cherché à savoir pouquoi mon IBQUERY ne voulait pas me passer la requête que j'avais pensé qu'il fallait l'empêcher de s'exécuter
    , un peu à la manière d'un
    en PHP qui va AFFICHER ; et ne va pas l'interpréter.

    Comme quoi, on s'égare parfois .... Faudrait que je laisse reposer mon neurone....
    Oui je connais ça, parfois pour résoudre un probleme on le fait de manière empirique. On essaye différentes possibilitées en changeant un ou plusieurs paramètres. Au bout d'un moment le problème étant plus complexe qu'on ne l'imaginait on ne rend compte qu'on a pas noté précisément tous les changement effectués et il devient difficile de se souvenir les différents tests déja réalisés... Pour peux que l'on arrive finalement à faire fonctionner la chose, reste à déduire sans faute "le pourquoi du comment"... Et dans ces cas là il vaut mieux le faire à tête reposée ou continuer l'expérimentation (jusqu a ce que ca ne marche plus) pour en déduire précisément le fonctionnement...

    Vous vous avez trouvé seul la solution (ce qui est déjà très bien et c'est souvent tout ce qu'on demande) mais vous vous êtes juste trompé sur la conclusion (ce qui arrive souvant dans le feu de l'action).

    Amicalement
    Barbibulle

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

Discussions similaires

  1. Création de triggers sous PHPMyAdmin
    Par MakorDal dans le forum SQL Procédural
    Réponses: 2
    Dernier message: 25/02/2007, 18h50
  2. [MySQL] Création de trigger depuis PHP
    Par Shiva dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 12/01/2007, 13h16
  3. [Débutant] Création de trigger
    Par steph_batman dans le forum Développement
    Réponses: 4
    Dernier message: 06/12/2006, 16h44
  4. [PL/SQL] [9i] Pblm lors de la création de triggers
    Par ftrifiro dans le forum Oracle
    Réponses: 3
    Dernier message: 27/06/2006, 15h08
  5. [IB][IBQUERY][D7 pro] Procédure stockée ne renvoit rien
    Par N1bus dans le forum Bases de données
    Réponses: 7
    Dernier message: 16/10/2004, 23h33

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