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

Composants VCL Delphi Discussion :

[D2010] Comment créer dynamiquement une TSQLStoredProc ?


Sujet :

Composants VCL Delphi

  1. #1
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 664
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 664
    Points : 6 967
    Points
    6 967
    Par défaut [D2010] Comment créer dynamiquement une TSQLStoredProc ?
    Jusqu'à présent, j'utilisais sans problème la TStoredProc du BDE sous Delphi 6 (avec Oracle 10g).
    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
    function ProduitEphemere(const szRacinePdt, szFinitPdt: String; Database: TDatabase): Integer;
    var
       StoredProc: TStoredProc;
    begin
       Result := 0;
       StoredProc := TStoredProc.Create(nil);
       try
          StoredProc.DatabaseName := Database.DatabaseName;
          StoredProc.StoredProcName := 'EST_UN_PRODUIT_EPHEMERE';
          StoredProc.Params.CreateParam(ftString, 'pRACINE_PDT', ptInput);
          StoredProc.Params.CreateParam(ftString, 'pFINIT_PDT', ptInput);
          StoredProc.Params.CreateParam(ftFloat, 'Résultat', ptResult);
          try
             StoredProc.ParamByName('pRACINE_PDT').AsString := szRacinePdt;
             StoredProc.ParamByName('pFINIT_PDT').AsString := szFinitPdt;
             StoredProc.ExecProc;
             Result := StoredProc.ParamByName('Résultat').AsInteger;
          except
             on E: Exception do
             begin
                // Erreur ...
                Exit;
             end;
          end;
       finally
          StoredProc.Free;
       end;
    end;
    Je commence à développer sous Delphi 2010, et je passe aux composants DBExpress.
    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
    function ProduitEphemere(const szRacinePdt, szFinitPdt: String; SQLConnection: TSQLConnection): Integer;
    var
       SQLStoredProc: TSQLStoredProc;
    begin
       Result := 0;
       SQLStoredProc := TSQLStoredProc.Create(nil);
       try
          SQLStoredProc.SQLConnection := SQLConnection;
          SQLStoredProc.StoredProcName := 'EST_UN_PRODUIT_EPHEMERE';
          SQLStoredProc.Params.CreateParam(ftString, 'pRACINE_PDT', ptInput);
          SQLStoredProc.Params.CreateParam(ftString, 'pFINIT_PDT', ptInput);
          SQLStoredProc.Params.CreateParam(ftFMTBcd, 'Result', ptResult);
          try
             SQLStoredProc.ParamByName('pRACINE_PDT').AsString := szRacinePdt;
             SQLStoredProc.ParamByName('pFINIT_PDT').AsString := szFinitPdt;
             SQLStoredProc.ExecProc;
             Result := SQLStoredProc.ParamByName('Result').AsInteger;
          except
             on E: Exception do
             begin
                // Erreur ...
                Exit;
             end;
          end;
       finally
          SQLStoredProc.Free;
       end;
    end;
    Et là, j'ai une erreur :
    "EST_UN_PRODUIT_EPHEMERE" : Le nombre réel de paramètres (4) a dépassé le nombre en cours de paramètres de procédure stockée (3). Désactivez la propriété de composant ParamCheck ou vérifiez le contenu de la liste de paramètres
    J'ai donc ajouté SQLStoredProc.ParamCheck := False;, et j'obtiens une erreur PL/SQL. La fonction plante, car elle a reçu le contenu du deuxième paramètre dans le premier, et rien dans le deuxième.

    Que faut-il faut faire pour créer convenablement ces paramètres ?

    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. ___ Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.3.2 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.1 Entreprise
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.4)

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Que contient "Params" avant d'en Créer ?
    Il n'ajouterait pas un paramètre Result par Défaut ?
    un petit Clear() par prudence même si avec un objet créé à la volée ça ne devrait pas être utilse

    as-tu essayé des variantes sur ptResult et ptOutput ?
    ftFMTBcd est-il correctement supporté ?
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre chevronné

    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2002
    Messages
    1 288
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2002
    Messages : 1 288
    Points : 1 936
    Points
    1 936
    Par défaut
    Par défaut (comportement Delphi 7), quand tu affectes le nom de la procédure stockée, l'objet récupère la liste des paramètres.

    Par contre, le souci que j'ai eu (avec oracle 11g), c'est que j'ai dû passer par les indices (Params[0]), parce qu'avec FieldByName ça ne passait pas le bon paramètre. (alors que ça fonctionne avec Oracle 9i).

    Je ne sais pas quels comportements sont imputables à l'ancienneté de mon Delphi. J'espère avoir pu aider.
    Delphi 7/XE2/XE3
    C#
    Oracle 9i à 12c
    SQL Server 2008 à 2014

  4. #4
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 664
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 664
    Points : 6 967
    Points
    6 967
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Que contient "Params" avant d'en Créer ?
    Params.Count vaut 0.

    Citation Envoyé par ShaiLeTroll Voir le message
    Il n'ajouterait pas un paramètre Result par Défaut ?
    Si je ne créé pas le paramètre Result, il ne voit plus la procédure comme une fonction (semble t'il):
    PLS-00221: 'EST_UN_PRODUIT_EPHEMERE' is not a procedure or is undefined
    Citation Envoyé par ShaiLeTroll Voir le message
    un petit Clear() par prudence même si avec un objet créé à la volée ça ne devrait pas être utilse
    Ca ne change rien.

    Citation Envoyé par ShaiLeTroll Voir le message
    as-tu essayé des variantes sur ptResult et ptOutput ?
    Quel que soit le type du paramètre, si je le change en ptOutput j'obtiens l'erreur :
    Erreur DBX : Précision non valide


    Citation Envoyé par ShaiLeTroll Voir le message
    ftFMTBcd est-il correctement supporté ?
    C'est à dire ?
    Je ne l'utilise que parce qu'en conception, c'est le type qu'il choisit pour ce paramètre (quand je pose une SQLStoredProc en conception).

    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. ___ Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.3.2 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.1 Entreprise
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.4)

  5. #5
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 664
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 664
    Points : 6 967
    Points
    6 967
    Par défaut
    Citation Envoyé par Linkin Voir le message
    Par défaut (comportement Delphi 7), quand tu affectes le nom de la procédure stockée, l'objet récupère la liste des paramètres.
    Aaaaaarg !!
    Tu as raison. Ca les récupère tout seul.
    (depuis ce matin, que je suis dessus)

    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
    function ProduitEphemere(const szRacinePdt, szFinitPdt: String; SQLConnection: TSQLConnection): Integer;
    var
       SQLStoredProc: TSQLStoredProc;
    begin
       Result := 0;
       SQLStoredProc := TSQLStoredProc.Create(nil);
       try
          SQLStoredProc.SQLConnection := SQLConnection;
          SQLStoredProc.StoredProcName := 'EST_UN_PRODUIT_EPHEMERE';
          try
             SQLStoredProc.ParamByName('pRACINE_PDT').AsString := szRacinePdt;
             SQLStoredProc.ParamByName('pFINIT_PDT').AsString := szFinitPdt;
             SQLStoredProc.ExecProc;
             Result := SQLStoredProc.ParamByName('Result').AsInteger;
          except
             on E: Exception do
             begin
                // Erreur ...
                Exit;
             end;
          end;
       finally
          SQLStoredProc.Free;
       end;
    end;
    Citation Envoyé par Linkin Voir le message
    Par contre, le souci que j'ai eu (avec oracle 11g), c'est que j'ai dû passer par les indices (Params[0]), parce qu'avec FieldByName ça ne passait pas le bon paramètre. (alors que ça fonctionne avec Oracle 9i).
    Avec Delphi 2010 et Oracle 10g, je peux les appeler par leur nom sans problème.

    pour votre aide.
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. ___ Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.3.2 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.1 Entreprise
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.4)

  6. #6
    Candidat au Club
    Inscrit en
    Juin 2006
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    bonjour,

    est ce que je peux avoir le code (ou l’entête) de ta procédure car je me suis inspiré de ton code mais ça ne marche pas

    j'ai fais ma procédure comme ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    create or replace procedure EST_UN_PRODUIT_EPHEMERE (
    pRACINE_PDT in  varchar2,
    pFINIT_PDT in varchar2, 
    Résultat out varchar2 ) 
    is 
    begin
      Résultat := '12';
      ...
    end;/

  7. #7
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Déjà 'Result' est un entier dans l'extrait de code de Lung !

    Et ta démarche est étrange, on commence plutôt par créer la fonction doit l'on a besoin avec les paramètres nécessaires puis l'on fait le code d'appel

    Sinon, ce sujet étant , ce n'est pas pratique de le poursuivre en posant une nouvelle question !
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  8. #8
    Candidat au Club
    Inscrit en
    Juin 2006
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    Désolé d'avoir polluer
    Le problème était que dans Delphi je passais les paramètres en tant qu'entier.
    J'ai tout mis en type string et ça marche.
    merci.

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 09/08/2005, 17h38
  2. [Hibernate] Comment créer dynamiquement un fetching plan
    Par mauvais_karma dans le forum Hibernate
    Réponses: 15
    Dernier message: 08/08/2005, 09h40
  3. est il possible de créer dynamiquement une class ???
    Par SpaceFrog dans le forum Général JavaScript
    Réponses: 9
    Dernier message: 12/07/2005, 16h22
  4. [MFC] Créer dynamiquement une classe
    Par vanitom dans le forum MFC
    Réponses: 9
    Dernier message: 11/12/2004, 13h23

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