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 :

[Firedac] FDConnection.ExecSQL et paramètres


Sujet :

Bases de données Delphi

  1. #1
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 036
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 036
    Points : 40 941
    Points
    40 941
    Billets dans le blog
    62
    Par défaut [Firedac] FDConnection.ExecSQL et paramètres
    Bonjour,

    j'utilise souvent ce genre de code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FDConnection.ExecSQL('UPDATE EXPEDITION_ENTETE SET ETAT=3 WHERE NUMERO=?',[NBL]);
    Je me trouve confronté à un SQL de ce genre et donc une question pour Expert Firedac
    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
     
    // syntaxe non vérifiée
    SQLUPDTLCMDCLI='UPDATE LCMDCLI SET '+
                    'QTELIV1=IIF(QTELIV1+:Q1>QTECDE1,QTECDE1,QTELIV1+:Q1),'+
                    'QTELIV2=IIF(QTELIV2+:Q2>QTECDE2,QTECDE2,QTELIV2+:Q2),'+
                    'QTELIV3=IIF(QTELIV3+:Q3>QTECDE3,QTECDE3,QTELIV3+:Q3),'+
                    'QTELIV4=IIF(QTELIV4+:Q4>QTECDE4,QTECDE4,QTELIV4+:Q4),'+
                    'QTELIV5=IIF(QTELIV5+:Q5>QTECDE5,QTECDE5,QTELIV5+:Q5),'+
                    'QTELIV6=IIF(QTELIV6+:Q6>QTECDE6,QTECDE6,QTELIV6+:Q6),'+
                    'QTELIV7=IIF(QTELIV7+:Q7>QTECDE7,QTECDE7,QTELIV7+:Q7),'+
                    'QTELIV8=IIF(QTELIV8+:Q8>QTECDE8,QTECDE8,QTELIV8+:Q8),'+
                    'QTELIV9=IIF(QTELIV9+:Q9>QTECDE9,QTECDE9,QTELIV9+:Q9),'+
                    'QTELIV10=IIF(QTELIV10+:Q10>QTECDE10,QTECDE10,QTELIV10+:Q10),'+
                    'QTELIV11=IIF(QTELIV11+:Q11>QTECDE11,QTECDE11,QTELIV11+:Q11),'+
                    'QTELIV12=IIF(QTELIV12+:Q12>QTECDE12,QTECDE12,QTELIV12+:Q12),'+
                    'QTELIV13=IIF(QTELIV13+:Q13>QTECDE13,QTECDE13,QTELIV13+:Q13),'+
                    'QTELIV14=IIF(QTELIV14+:Q14>QTECDE14,QTECDE14,QTELIV14+:Q14),'+
                    'QTELIV15=IIF(QTELIV15+:Q15>QTECDE15,QTECDE15,QTELIV15+:Q15),'+
                    'QTELIV16=IIF(QTELIV16+:Q16>QTECDE16,QTECDE16,QTELIV16+:Q16),'+
                    'QTELIV17=IIF(QTELIV17+:Q17>QTECDE17,QTECDE17,QTELIV17+:Q17),'+
                    'QTELIV18=IIF(QTELIV18+:Q18>QTECDE18,QTECDE18,QTELIV18+:Q18),'+
                    'QTELIV19=IIF(QTELIV19+:Q19>QTECDE19,QTECDE19,QTELIV19+:Q19),'+
                    'QTELIV20=IIF(QTELIV20+:Q20>QTECDE20,QTECDE20,QTELIV20+:Q20),'+
                    'QTELIV21=IIF(QTELIV21+:Q21>QTECDE21,QTECDE21,QTELIV21+:Q21),'+
                    'QTELIV22=IIF(QTELIV22+:Q22>QTECDE22,QTECDE22,QTELIV22+:Q22),'+
                    'QTELIV23=IIF(QTELIV23+:Q23>QTECDE23,QTECDE23,QTELIV23+:Q23),'+
                    'QTELIV24=IIF(QTELIV24+:Q24>QTECDE24,QTECDE24,QTELIV24+:Q24) '+
                    'WHERE SAISON_CMDE=:SC AND NUM_CMDE=NC AND LIGNE=:L';
    Qui m'oblige donc à doubler pas mal de paramètres
    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
         ConnexionUS.ExecSQL(SQLUPDTLCMDCLI,
                               [Q.FieldbyName('Q1').asInteger,Q.FieldbyName('Q1').AsInteger,
                                Q.FieldbyName('Q2').asInteger,Q.FieldbyName('Q2').AsInteger,
                                Q.FieldbyName('Q3').asInteger,Q.FieldbyName('Q3').AsInteger,
                                Q.FieldbyName('Q4').asInteger,Q.FieldbyName('Q4').AsInteger,
                                Q.FieldbyName('Q5').asInteger,Q.FieldbyName('Q5').AsInteger,
                                Q.FieldbyName('Q6').asInteger,Q.FieldbyName('Q6').AsInteger,
                                Q.FieldbyName('Q7').asInteger,Q.FieldbyName('Q7').AsInteger,
                                Q.FieldbyName('Q8').asInteger,Q.FieldbyName('Q8').AsInteger,
                                Q.FieldbyName('Q9').asInteger,Q.FieldbyName('Q9').AsInteger,
                                Q.FieldbyName('Q10').asInteger,Q.FieldbyName('Q10').AsInteger,
                                Q.FieldbyName('Q11').asInteger,Q.FieldbyName('Q11').AsInteger,
                                Q.FieldbyName('Q12').asInteger,Q.FieldbyName('Q12').AsInteger,
                                Q.FieldbyName('Q13').asInteger,Q.FieldbyName('Q13').AsInteger,
                                Q.FieldbyName('Q14').asInteger,Q.FieldbyName('Q14').AsInteger,
                                Q.FieldbyName('Q15').asInteger,Q.FieldbyName('Q15').AsInteger,
                                Q.FieldbyName('Q16').asInteger,Q.FieldbyName('Q16').AsInteger,
                                Q.FieldbyName('Q17').asInteger,Q.FieldbyName('Q17').AsInteger,
                                Q.FieldbyName('Q18').asInteger,Q.FieldbyName('Q18').AsInteger,
                                Q.FieldbyName('Q19').asInteger,Q.FieldbyName('Q19').AsInteger,
                                Q.FieldbyName('Q20').asInteger,Q.FieldbyName('Q20').AsInteger,
                                Q.FieldbyName('Q21').asInteger,Q.FieldbyName('Q21').AsInteger,
                                Q.FieldbyName('Q22').asInteger,Q.FieldbyName('Q22').AsInteger,
                                Q.FieldbyName('Q23').asInteger,Q.FieldbyName('Q23').AsInteger,
                                Q.FieldbyName('Q24').asInteger,Q.FieldbyName('Q24').AsInteger,
                                Q.FieldbyName('SAISON_CMDE').asString,
                                Q.FieldbyName('NUM_CMDE').asInteger,
                                Q.FieldbyName('LIGNE').asInteger
                                ]);
    Je me demandais s'il n'y avait pas une syntaxe qui me permettrait d'éviter le dédoublement genre [Q1=Q.FieldbyName('Q1').asInteger,Q2=Q.FieldbyName('Q2').asInteger, ....]
    Je n'ai pas encore épluché ma Bible (Delphi in Depth : Firedac) et j'avoue le cas est un peu tiré par les cheveux. Il me semble avoir lu quelque part ce genre de syntaxe mais si un connaisseur Firedac a déjà la réponse merci.

    Bien sûr j'envisage d'autres solutions peut-être moins brutales avec un FDQuery avec son ParamByname je n'aurais pas ce "doublement"
    toutefois, il y a souvent plusieurs lignes à modifier, j'envisage donc aussi un ArrayDML du coup cela reste du même accabit
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  2. #2
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 688
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 688
    Points : 13 117
    Points
    13 117
    Par défaut
    TFDConnection traite les paramètres par nom et non par position. L'ordre n'est important que pour l'assignation (prochain paramètre = prochaine valeur non utilisée).

    Un exemple (MySQL) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    DM.DBLocal.ExecSQL('SELECT BodyID FROM Sales_Body WHERE ID=:ID AND ParentID=:ParentID AND Code=GetDBCode("ReserveUsed") INTO @UsedID;'
                      +'UPDATE Sales_Body SET Active = 0 WHERE ID = :ID AND ParentID = :ParentID;'
                      +'UPDATE Reservation SET UsedID = NULL WHERE ID = :ID AND UsedID = @UsedID;',
                      [ID, qSaleBodyParentID.AsInteger]);

  3. #3
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 036
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 036
    Points : 40 941
    Points
    40 941
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    Tu me confortes dans l'idée de la possiblité de mettre plusieurs SQL en un seul EXECSQL même si je suis frileux à ce sujet.
    Mais, d'un autre côté ton exemple est un cas particulier, chacun des SQL ayant les mêmes paramêtres.

    par contre
    TFDConnection traite les paramètres par nom et non par position.
    cette assertion me semble fausse, pour preuve tu peux remplacer les paramêtres nommés par des ?, je dirais donc plutôt qu'il s'agit des positions plutôt que des noms. Cela risque de devenir un débat

    Il faut vraiment que je me replonge dans ma bible, mais comme c'est quand même un cas particulier je ne sais si je vais découvrir le pot aux roses. Je vais peut-être posé la question sur le forum Embarcadero, Dmitry Arefiev semble encore y répondre de temps en temps on aurait la réponse de l'auteur principal.
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  4. #4
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 036
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 036
    Points : 40 941
    Points
    40 941
    Billets dans le blog
    62
    Par défaut
    Après épluchage de la "Bible", c’est-à-dire une recherche dans la table des matières et lecture des diverses pages pointées j'ai ceci qui tranche le débat et répond à ma question (page 120/121)

    je résume le paragraphe en extrayant et traduisant une phrase (répétée sous diverses formes)
    Citation Envoyé par Cary Jensen
    Lorsque vous utilisez des paramètres de position, vous devez fournir une valeur pour chaque marqueur de paramètre de position
    Donc, pour me répondre, non il n'y a pas moyen (dans le cas d'un FDConnection.ExecSQL) de réduire.
    Je crois que dans le cas particulier d'un FDConnection que les paramètres soient nommés ou non, cela reste des paramètres positionnels (à confirmer)

    @AndNotOr dans ton exemple quid en cas de gestion de la transaction ?
    1 - Déjà, comme j'avais pu le découvrir, la transaction qui est utilisée est-celle de la propriété Transaction et non UpdateTransaction.
    2- Si aucun FDTransaction n'est défini alors le comportement va peut-être bien différer entre les versions ante 10.4 et post 10.4 cf ce billet
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  5. #5
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 688
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 688
    Points : 13 117
    Points
    13 117
    Par défaut
    Les paramètres anonymes sont sans doute traités par position (comment pourrait-il en être autrement) mais les paramètres nommés sont traités par nom au niveau de TFDConnection. TFDQuery lui laisse le choix par sa propriété BindMode mais est par nom par défaut.

    A noter que les paramètres anonymes, sans être dépréciés, ne sont pas recommandés non plus

    Ici :Qty est utilisé à deux reprises dans la même requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    DM.DBLocal.ExecSQL('INSERT INTO Invoices_Body (ID, BodyID, InvoiceID, StockID, RefID, Qty) '
                      +' VALUES '
                      +'(:ID, @BodyID, :InvoiceID, :StockID, :RefID, :Qty) '
                      +'ON DUPLICATE KEY UPDATE Qty=Qty +:Qty;',
                      [Invoice.ID, Invoice.InvoiceID, aID, aRefID, aQty])

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 15/09/2016, 12h16
  2. [Firedac] [XE4] ADConnection.ExecSQL avec paramètres
    Par SergioMaster dans le forum Bases de données
    Réponses: 2
    Dernier message: 21/03/2014, 08h05
  3. [SWT] Problème de paramètre GridData
    Par yolepro dans le forum SWT/JFace
    Réponses: 4
    Dernier message: 06/12/2002, 10h37
  4. passage en paramètre d'un array dynamique 2D
    Par Guigui_ dans le forum Langage
    Réponses: 4
    Dernier message: 27/11/2002, 19h47
  5. Paramètre requete SQL (ADOQuery)
    Par GaL dans le forum C++Builder
    Réponses: 3
    Dernier message: 30/07/2002, 11h24

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