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 :

[ADO][SqlServer] Pb avec les paramètres dans les expressions


Sujet :

Bases de données Delphi

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    158
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2005
    Messages : 158
    Points : 158
    Points
    158
    Par défaut [ADO][SqlServer] Pb avec les paramètres dans les expressions
    Bonjour,

    Dans le cas d'une migration BDE en ADO, je me retrouve avec le problème suivant.

    Lorsque dans une requête, il y a des paramètres à la fois dans l'expression et dans sa close where, ma requête "ADO" lors de l'évaluation du paramcheck plante sur "mémoire insuffisante".

    Si je prends ce cas suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    With MaRequete do
    begin
    Close;
    SQL.Clear;
    SQL.Add('select Monchamp1,(select Monchamp2 from LaTable2 where 
    Monchamp2 = :PChamp2)
    from LaTable1 ');
    SQL.Add('Where Monchamp1 = :PChamp1);
    ParamCheck := True;
    ParamByName('PChamp1').Value := 'Test';
    ParamByName('PChamp2').Value := 'Test';
    Open;
    end;
    cela plante ( Pour info en BDE cela ne pose aucun problème)

    par contre dans les 2 cas qui suivent cela passe normalement

    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
      // Le paramètre est uniquement dans la close where
       
      With MaRequete do
    begin
    Close;
    SQL.Clear;
    SQL.Add('select Monchamp1,(select Monchamp2 from LaTable2 where 
    Monchamp2 = 'Test')
    from LaTable1 ');
    SQL.Add('Where Monchamp1 = :PChamp1);
    ParamCheck := True;
    ParamByName('PChamp1').Value := 'Test';
    //ParamByName('PChamp2').Value := 'Test';
    Open;
    end;
    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
     // Le paramètre est uniquement dans l’expression
       
      With MaRequete do
    begin
    Close;
    SQL.Clear;
    SQL.Add('select Monchamp1,(select Monchamp2 from LaTable2 where 
    Monchamp2 = 'Test')
    from LaTable1 ');
    SQL.Add('Where Monchamp1 = 'Test');
    ParamCheck := True;
    //ParamByName('PChamp1').Value := 'Test';
    ParamByName('PChamp2').Value := 'Test';
    Open;
    end;
    Avez vous une idée , d’où pourrait venir le problème ?

    Merci pour vos réponses.

  2. #2
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 235
    Points : 8 504
    Points
    8 504
    Par défaut
    Mon dieu mais quelle requete horrible

    Elle doit faire quoi ta requete ?

    Le MonChamp1 = le MonChamp2 ?

    Des requetes de ce style c'est à banir ...

    Donne ous des infos pour qu'on te sorte une requete beaucoup mieux que celle la.

  3. #3
    Membre éclairé Avatar de slimjoe
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2005
    Messages : 647
    Points : 789
    Points
    789
    Par défaut
    Salut!

    En ADO, la méthode ParamByName est encapsulée dans l'objet Parameters. Il faut donc faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
      with MaRequete do
      begin
        Close;
        SQL.Clear;
        SQL.Add('select Monchamp1, (select Monchamp2 from LaTable2 where Monchamp2 = :PChamp2) from LaTable1');
        SQL.Add('Where Monchamp1 = :PChamp1');
        ParamCheck := True;
        Parameters.ParamByName('PChamp1').Value := 'Test';
        Parameters.ParamByName('PChamp2').Value := 'Test';
        Open;
      end;
    Ceci dit, avec le message d'erreur, c'est plus facile de diagnostiquer ("ça plante" n'est pas un diagnostic valide

  4. #4
    Membre éclairé Avatar de slimjoe
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2005
    Messages : 647
    Points : 789
    Points
    789
    Par défaut
    Citation Envoyé par Malatar
    Mon dieu mais quelle requete horrible

    [...]

    Des requetes de ce style c'est à banir ...

    Donne ous des infos pour qu'on te sorte une requete beaucoup mieux que celle la.
    +1

    Parfaitement d'accord!

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    158
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2005
    Messages : 158
    Points : 158
    Points
    158
    Par défaut
    Bonjour,

    je vous remercie pour vos réponses.

    J'ai mis une requête générique pour l'exemple, car je ne peux pas vous mettre la requête en prod qui est trop longue,
    mais c'était surtout le principe que je voulais avoir avec vous
    c'est à dire le fait d'utiliser des paramètres à la fois dans les expressions et dans la close where.

    Merci

  6. #6
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Salut

    Même si elle est longue, tu peux quand même nous la montrer cette requête.
    Car je suis d'accord avec Malatar et SlimJoe, ton exemple de requête n'a rien de générique !!!

    @+ Claudius

  7. #7
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    158
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2005
    Messages : 158
    Points : 158
    Points
    158
    Par défaut
    Voici exprimée je l'espère de manière plus clair, le type de requête que je ne peux pas exécuter en ADO

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    select col,(select col from tab where col= :X1) from tab where col = :X2
    En essayant de coller ce SQL dans un ADOQuery en paramcheck à TRUE

    on obtient en mode design 'Violation accès dans ntdll.dll' puis à l'execution 'Violation d'accès dans rtl70.bpl' et dynamiquement par le code 'Mémoire insuffisante pour cette opération'.

    Merci
    Pour votre aide

    (PS : S'il le faut , je vous post la requête complète)

  8. #8
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 235
    Points : 8 504
    Points
    8 504
    Par défaut
    Ce que l'on te demande surtout c'est qu'est ce que tu veux faire avec ta requete finale.
    Une requete avec un select dans ses champs, c'est normalement à ne jamais faire.
    Je suis sûr qu'on peut transformer cette requete en une requete avec des jointures propres (et je suis sûr aussi qu'elle sera largement plus rapide à exécuter).

  9. #9
    Membre éclairé Avatar de slimjoe
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2005
    Messages : 647
    Points : 789
    Points
    789
    Par défaut
    Citation Envoyé par pitango
    Voici exprimée je l'espère de manière plus clair, le type de requête que je ne peux pas exécuter en ADO

    on obtient en mode design 'Violation accès dans ntdll.dll' puis à l'execution 'Violation d'accès dans rtl70.bpl' et dynamiquement par le code 'Mémoire insuffisante pour cette opération'.

    Ce code fonctionne parfaitement chez moi (D7 sur WinVista et SQL Express, MaRequete est un TADOQuery) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
      with MaRequete do
      begin
        Close;
        SQL.Clear;
        SQL.Add('select Monchamp1, (select Monchamp2 from LaTable2 where Monchamp2 = :PChamp2) from LaTable1');
        SQL.Add('Where Monchamp1 = :PChamp1');
        ParamCheck := True;
        Parameters.ParamByName('PChamp1').Value := 'Test';
        Parameters.ParamByName('PChamp2').Value := 'Test';
        Open;
      end;

  10. #10
    Rédacteur

    Profil pro
    Inscrit en
    Juin 2003
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 83
    Points : 28
    Points
    28
    Par défaut
    Effectivement, j'ai les mêmes erreurs, il semble que tu aies explosé le ParamCheck en ADO avec ce type de requête bizarre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select col,(select col from tab where col= :X1) from tab where col = :X2
    C'est un bug, quel que soit l'intérêt de la requête...

    Evidemment c'est contournable en utilisant les paramètres anonymes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select col,(select col from tab where col= ?) from tab where col = ?
    et ParamCheck à False, avec des CreateParameters au lieu de ParamByName...

  11. #11
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    158
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2005
    Messages : 158
    Points : 158
    Points
    158
    Par défaut
    Citation Envoyé par Slimjoe
    Ce code fonctionne parfaitement chez moi (D7 sur WinVista et SQL Express, MaRequete est un TADOQuery) :
    Nous n'avons pas tout à fait la même config, mais de mon coté rien à faire cela ne passe pas.

    sinon voici la requête complète pour info

    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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
     
    CO_RQT_LOTS_RECA := 
      ' select ' +
        '    right(''0'' + cast(TABLE040.SEQ_RAY as varchar(2)),2) as SEQ_RAY, ' +
        '    TABLE170.SEQ_FAM as SEQ_FAM, ' +
        '    (select ' +
        '        isnull(sum(T640INT.QTE_COMPTEE),0) ' +
        '     from ' +
        '             TABLE640 T640INT with (nolock) ' +
        '        join TABLE030 T030INT with (nolock) on (T640INT.ID_REF_PVT = T030INT.ID_REF_PVT and T640INT.ID_IT = T030INT.ID_IT) ' +
        '        join TABLE310 T310INT with (nolock) on T030INT.ID_REF_PVT = T310INT.ID_REF_PVT ' +
        '        join TABLE170 T170INT with (nolock) on (T310INT.ID_ENS = T170INT.ID_ENS and T310INT.SEQ_FAM_RAT = T170INT.SEQ_FAM) ' +
        '        join TABLE380 T380INT with (nolock) on (T170INT.ID_ENS = T380INT.ID_ENS and T170INT.SEQ_TRIBU = T380INT.SEQ_TRIBU) ' +
        '        join TABLE040 T040INT with (nolock) on (T380INT.ID_ENS = T040INT.ID_ENS and T380INT.SEQ_CHEF_PDT = T040INT.SEQ_CHEF_PDT) ' +
        '     where ' +
        '            T310INT.FLAG_TOP_SOLDE = 0 ' +
        '        and T310INT.ID_LR = :IdLr1 ' +
        '        and T640INT.DateTraitement = :DateTraitement2 ' +
        '        and T170INT.SEQ_FAM = TABLE170.SEQ_FAM ' +
        '        and T040INT.SEQ_RAY = TABLE040.SEQ_RAY) as QTE_COMPTEE, ' +
        '    (select ' +
        '        isnull(sum(T640INT.QTE_COMPTEE * T030INT.PRIX_VENTE),0) ' +
        '     from ' +
        '             TABLE640 T640INT with (nolock) ' +
        '        join TABLE030 T030INT with (nolock) on (T640INT.ID_REF_PVT = T030INT.ID_REF_PVT and T640INT.ID_IT = T030INT.ID_IT) ' +
        '        join TABLE310 T310INT with (nolock) on T030INT.ID_REF_PVT = T310INT.ID_REF_PVT ' +
        '        join TABLE170 T170INT with (nolock) on (T310INT.ID_ENS = T170INT.ID_ENS and T310INT.SEQ_FAM_RAT = T170INT.SEQ_FAM) ' +
        '        join TABLE380 T380INT with (nolock) on (T170INT.ID_ENS = T380INT.ID_ENS and T170INT.SEQ_TRIBU = T380INT.SEQ_TRIBU) ' +
        '        join TABLE040 T040INT with (nolock) on (T380INT.ID_ENS = T040INT.ID_ENS and T380INT.SEQ_CHEF_PDT = T040INT.SEQ_CHEF_PDT) ' +
        '     where' +
        '            T310INT.FLAG_TOP_SOLDE = 0 ' +
        '        and T310INT.ID_LR = :IdLr2 ' +
        '        and T640INT.DateTraitement = :DateTraitement2 ' +     
        '        and T170INT.SEQ_FAM = TABLE170.SEQ_FAM ' +
        '        and T040INT.SEQ_RAY = TABLE040.SEQ_RAY) as VALEUR, ' +
        '    (select ' +
        '        isnull(sum(T640INT.QTE_COMPTEE),0) ' +
        '     from ' +
        '             TABLE640 T640INT with (nolock) ' +
        '        join TABLE030 T030INT with (nolock) on (T640INT.ID_REF_PVT = T030INT.ID_REF_PVT and T640INT.ID_IT = T030INT.ID_IT) ' +
        '        join TABLE310 T310INT with (nolock) on T030INT.ID_REF_PVT = T310INT.ID_REF_PVT ' +
        '        join TABLE170 T170INT with (nolock) on (T310INT.ID_ENS = T170INT.ID_ENS and T310INT.SEQ_FAM_RAT = T170INT.SEQ_FAM) ' +
        '        join TABLE380 T380INT with (nolock) on (T170INT.ID_ENS = T380INT.ID_ENS and T170INT.SEQ_TRIBU = T380INT.SEQ_TRIBU) ' +
        '        join TABLE040 T040INT with (nolock) on (T380INT.ID_ENS = T040INT.ID_ENS and T380INT.SEQ_CHEF_PDT = T040INT.SEQ_CHEF_PDT) ' +
        '     where ' +
        '            T310INT.FLAG_TOP_SOLDE = 1 ' +
        '        and T310INT.ID_LR = :IdLr3 ' +
        '        and T640INT.DateTraitement = :DateTraitement3 ' +
        '        and T170INT.SEQ_FAM = TABLE170.SEQ_FAM ' +
        '        and T040INT.SEQ_RAY = TABLE040.SEQ_RAY) as QTE_SOLDE, ' +
        '    (select ' +
        '        isnull(sum(T640INT.QTE_COMPTEE * T030INT.PRIX_VENTE),0) ' +
        '     from ' +
        '             TABLE640 T640INT with (nolock) ' +
        '        join TABLE030 T030INT with (nolock) on (T640INT.ID_REF_PVT = T030INT.ID_REF_PVT and T640INT.ID_IT = T030INT.ID_IT) ' +
        '        join TABLE310 T310INT with (nolock) on T030INT.ID_REF_PVT = T310INT.ID_REF_PVT ' +
        '        join TABLE170 T170INT with (nolock) on (T310INT.ID_ENS = T170INT.ID_ENS and T310INT.SEQ_FAM_RAT = T170INT.SEQ_FAM) ' +
        '        join TABLE380 T380INT with (nolock) on (T170INT.ID_ENS = T380INT.ID_ENS and T170INT.SEQ_TRIBU = T380INT.SEQ_TRIBU) ' +
        '        join TABLE040 T040INT with (nolock) on (T380INT.ID_ENS = T040INT.ID_ENS and T380INT.SEQ_CHEF_PDT = T040INT.SEQ_CHEF_PDT) ' +
        '     where ' +
        '            T310INT.FLAG_TOP_SOLDE = 1 ' +
         '        and T310INT.ID_LR = :IdLr4 ' +
        '        and T640INT.DateTraitement = :DateTraitement4 ' +
        '        and T170INT.SEQ_FAM = TABLE170.SEQ_FAM ' +
        '        and T040INT.SEQ_RAY = TABLE040.SEQ_RAY) as VALEUR_S, ' +
        '    isnull(sum(TABLE640.QTE_COMPTEE),0) as TOT_QTE, ' +
        '    isnull(sum(TABLE640.QTE_COMPTEE * TABLE030.PRIX_VENTE),0) as TOT_VALEUR ' +
        ' ' +
        ' from ' +
        '         TABLE640 with (nolock) ' +
        '    join TABLE030 with (nolock) on (TABLE640.ID_REF_PVT = TABLE030.ID_REF_PVT and TABLE640.ID_IT = TABLE030.ID_IT) ' +
        '    join TABLE310 with (nolock) on TABLE030.ID_REF_PVT = TABLE310.ID_REF_PVT ' +
        '    join TABLE170 with (nolock) on (TABLE310.ID_ENS = TABLE170.ID_ENS and TABLE310.SEQ_FAM_RAT = TABLE170.SEQ_FAM) ' +
        '    join TABLE380 with (nolock) on (TABLE170.ID_ENS = TABLE380.ID_ENS and TABLE170.SEQ_TRIBU = TABLE380.SEQ_TRIBU) ' +
        '    join TABLE040 with (nolock) on (TABLE380.ID_ENS = TABLE040.ID_ENS and TABLE380.SEQ_CHEF_PDT = TABLE040.SEQ_CHEF_PDT) ' +
        ' ' +
        ' where ' +
        '        TABLE640.DateTraitement = :DateTraitement5 ' +
        '    and TABLE310.ID_LR = :IdLr5 ' +
        ' ' +
        ' group by ' +
        '    TABLE040.SEQ_RAY, ' +
        '    TABLE170.SEQ_FAM ' +
        ' ' +
        ' order by ' +
        '    TABLE040.SEQ_RAY, ' +
        '    TABLE170.SEQ_FAM ';
    Merci

    A+

  12. #12
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 235
    Points : 8 504
    Points
    8 504
    Par défaut
    Les paramètres IdLRx et DateTraitmentx sont différents pour chaque requete ou sont ils identiques pour chacun ?

  13. #13
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    158
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2005
    Messages : 158
    Points : 158
    Points
    158
    Par défaut
    Citation Envoyé par Malatar
    tLes paramètres IdLRx et DateTraitmentx sont différents pour chaque requete ou sont ils identiques pour chacun ?
    Les paramètres sont identiques (Pour info , le problème reste le même si nous avons qu'un seul paramètre)

    Merci

  14. #14
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    158
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2005
    Messages : 158
    Points : 158
    Points
    158
    Par défaut
    Bonjour pour info,

    le problème que j'avais signalé se produit également en Delphi 2007.

    Le support de Codegear m'a confirmé après analyse, un bug avec les ADO et me propose de contourner le pb par exemple avec DBexpress. (Dans mon cas c'est impossible mais bon on va faire autrement).

    ci-joint un exemple du problème en Delphi 2007

    Je cloture ce post qui n'est pas vraiment résolu.....


    Images attachées Images attachées  

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 06/08/2009, 18h09
  2. les classes et les templates dans les plugins
    Par asoka13 dans le forum C++
    Réponses: 22
    Dernier message: 24/01/2008, 18h11
  3. Réponses: 2
    Dernier message: 22/08/2007, 13h46
  4. Réponses: 4
    Dernier message: 11/09/2006, 17h55
  5. Les polices dans les tables et les requêts
    Par zooffy dans le forum Access
    Réponses: 3
    Dernier message: 21/06/2006, 12h06

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