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

Lazarus Pascal Discussion :

Erreur dans requête paramétrée


Sujet :

Lazarus Pascal

  1. #1
    Membre du Club
    Erreur dans requête paramétrée
    Bonjour à toutes et à tous.
    Ma configuration : Windows 10; Lazarus 2.0.6 sur FPC 3.0.4
    Le programme sert à manipuler des normes NF, EN et ISO.
    Un DataModule est créé dans le fichier programme par :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    Application.CreateForm(TModuleDonnees, ModuleDonnees);

    Ce DataModule est composé d'un TPQConnection et d'un TSQLTransaction qui sont initialisés grâce à cette procedure :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    procedure TModuleDonnees.DataModuleCreate(Sender: TObject);
    begin
      ConnexionPQ.DatabaseName := 'aaaaaaa';
      ConnexionPQ.UserName := 'postgres';
      ConnexionPQ.HostName := 'localhost';
      ConnexionPQ.Password := 'xxxxxxx';
      //ConnexionPQ.Connected := true; Automatique lors d'un SQLQuery.Open
      ConnexionPQ.Transaction := TransactionSQL;
      TransactionSQL.DataBase := ConnexionPQ;
      //TransactionSQL.Active := true;  Automatique lors d'un SQLQuery.Open
    end;

    Jusque là tout fonctionne dans l'utilisation de ce module de données par d'autres fiches. Une nouvelle fiche sert à modifier le répertoire de sauvegarde des normes. Sur cette fiche sont déposés un TDBText, qui rappelle le répertoire actuel de sauvegarde à partir d'une requête dans la base de données (cela fonctionne), un TEdit où l'utilisateur précise le nouveau répertoire de sauvegarde et un TButton qui valide le changement et ferme la fiche. Voici le code de ce bouton sans le contrôle de la non nullité du TEdit :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    RN := TSQLQuery.Create(nil);
      SN := TDataSource.Create(nil);
      RN.Database := ModuleDonnees.ConnexionPQ;
      SN.DataSet := RN;
      RN.UpdateSQL.Text := 'UPDATE s_ent.t_e_norme_nor SET nor_repertoire=:REP;';
      RN.Params.ParamByName('REP').AsString := ENouveauRepertoire.Text;
      SN.Enabled := true;
      RN.Active := true;
      RN.ExecSQL;
      ModuleDonnees.TransactionSQL.Commit;
      RN.Close;
      ModuleDonnees.TransactionSQL.Active := false;
      ModuleDonnees.ConnexionPQ.Connected := false;
      Close;

    La compilation s'effectue sans sourciller mais à l'utilisation l'erreur suivante surgit :
    Le projet Normes a levé une classe d'exception 'EDatabaseError' avec le message :
    Parameter "REP" not found.
    Erreur qui apparaît aussi en lançant le programme par Normes.exe.
    Votre aide est donc sollicitée pour résoudre ce problème et je vous remercie à l'avance de me dépanner.
    Michel.

  2. #2
    Modérateur

    Bonsoir,
    Que vaut RN.Params.Count (ou équivalent) ?
    Et RN.Params[0].AsString := ENouveauRepertoire.Text; fonctionne-t-il ?
    Delphi 5 Pro - Delphi 10.3.2 Rio Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  3. #3
    Membre du Club
    Merci pour l'intérêt que tu portes à mon problème.
    Que vaut RN.Params.Count (ou équivalent) ?
    Il vaut 0 révélé par un ShowMessage après RN.UpdateSQL.Text :=
    RN.Params[0].AsString := ENouveauRepertoire.Text; fonctionne-t-il ?
    Cela soulève une erreur : List index(0) out of bounds
    Je vais essayer de ne plus créer SQLQuery par programmation mais en déposant le composant dans la fiche et je rends compte.
    Merci encore pour ton aide.
    Michel.

  4. #4
    Modérateur

    Voici une piste qui a l'air solide : https://forum.lazarus.freepascal.org/index.php?topic=17725.0.
    Delphi 5 Pro - Delphi 10.3.2 Rio Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  5. #5
    Membre du Club
    Bonjour.
    Je suis en train de suivre cette piste qui me montre que je n'ai rien compris aux TdataSet et TSQLQuery! Mais je m'accroche.
    Michel.

  6. #6
    Membre du Club
    Bonjour.
    Maintenant cela fonctionne. Voici les modifications apportées, certaines sans conséquences et d'autres plus fondamentales.
    Sur la fiche, dépose d'un DBEdit (DBEReprtoire) et d'un bouton de sauvegarde/quitter (BtnSauvegarderQuitter).
    Procedure de création de la fiche :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    procedure TFicheChangerRepertoire.FormCreate(Sender: TObject);
    begin
      RR := TSQLQuery.Create(nil);
      SR := TDataSource.Create(nil);
      RR.Database := ModuleDonnees.ConnexionPQ;
      SR.DataSet := RR;
      RR.SQL.Text := 'SELECT nor_repertoire FROM s_ent.t_e_norme_nor;';
      RR.DataBase := ModuleDonnees.ConnexionPQ;
      RR.Active := true;
      SR.Enabled := true;
      DBERepertoire.DataSource := SR;
      DBERepertoire.DataField := 'nor_repertoire';
      AncienRepertoire := DBERepertoire.Field.Text;
    end;

    Procedure de l'évènement d'action sur le bouton :
    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
    procedure TFicheChangerRepertoire.BtnSauvegarderQuitterClick(Sender: TObject);
    begin
      RR.SQL.Text := 'UPDATE s_ent.t_e_norme_nor SET nor_repertoire = :REP;';
      RR.Params.ParamByName('REP').AsString := DBERepertoire.Field.Text;
      try
        RR.ExecSQL;
        ModuleDonnees.TransactionSQL.Commit;
        ShowMessage('Succès de la mise à jour');
      except on e: Exception do
        ShowMessage(e.Message);
      end;
      RR.Close;
      ModuleDonnees.TransactionSQL.Active := false;
      ModuleDonnees.ConnexionPQ.Connected := false;
      Close;
    end;

    J'ai utilisé le même composant TSQLQuery dans les deux procédures et c'est ce qui a tout changé. Ce que j'en déduis, c'est que le DataSet doit être ouvert par un "SELECT" avant d'utiliser un ExecSQL. Me trompe-je?
    Il ne me reste qu'à lancer cette requête :
    Code sql :Sélectionner tout -Visualiser dans une fenêtre à part
    ALTER TABLE s_ent.t_e_norme_nor ALTER COLUMN nor_repertoire SET DEFAULT DBERepertoire.Field.Text;

    pour modifier la valeur par défaut de "nor_repertoire" et éviter de la taper lors d'une insertion de nouvelle norme.
    Michel.

###raw>template_hook.ano_emploi###