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 :

TField Curvalue Oldvalue Newvalue et AFO


Sujet :

Bases de données Delphi

  1. #1
    Membre régulier
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Octobre 2006
    Messages
    127
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 127
    Points : 74
    Points
    74
    Par défaut TField Curvalue Oldvalue Newvalue et AFO
    Bonjour
    La procedure suivante plante "Operation de variant incorrecte" sur le f.OldValue <> F.Newvalue quand le champ est de type TBCDField, donc qu'à cela ne tienne, je passe EnableBCD à false et transforme ainsi le type TBCDField en TFloatField mais j'ai toujours l'une erreur sur les champs ainsi retypés

    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
     
    procedure TEditionDevisForm.UpdateDevispartQuery(const aq:TADOQuery);
    var
      ad:TADOCommand;
      ct,fl:TStringList;
      i:integer;
      f:TField;
    begin
      ad:=TADOCommand.create(nil);
      ct:=TStringList.create;
      fl:=TStringList.create;
      try
        ad.Connection:=MainDM.MainConnection;
        ad.CommandType:=cmdText;
        ct.add('UPDATE T_DEVPART_DPT SET');
        for i:=0 to aq.FieldCount - 1 do
        begin
          f:=aq.Fields[i];
          if (f.OldValue <> f.Newvalue) then
          begin
            fl.add(f.FieldName);
            ct.add(f.FieldName + '=:' + f.FieldName);
          end;
        end;
        ct.add('WHERE DPT_ID = ' + IntToStr(aq.FieldByName('DPT_ID').value));
        for i:=0 to fl.Count - 1 do
        begin
          f:=aq.FindField(fl[i]);
          ad.Parameters.CreateParameter(f.FieldName, f.dataType, pdInput, f.Size, f.Newvalue);
        end;
        ad.CommandText:= ct.GetText;
        ad.Execute;
      finally
        fl.free;
        ct.free;
        ad.free;
      end;
    end;
    Que de surprises avec ADO c'est à peine utilisable
    Bruno Petit

  2. #2
    Membre régulier
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Octobre 2006
    Messages
    127
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 127
    Points : 74
    Points
    74
    Par défaut
    J'ai oublié de préciser que c'était avec un ADOQuery en mode ltbatchOptimistic
    Bruno Petit

  3. #3
    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
    au lieu de :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
          if (f.OldValue <> f.Newvalue) then
    essai

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if not VarSameValue(f.OldValue,f.Newvalue) then
    Citation Envoyé par PickEpique Voir le message
    Que de surprises avec ADO c'est à peine utilisable
    Les TField n'ont rien à voir avec les unités ADO, Le BDE et IB utilisent aussi l'unité Db qui contient ces TField
    Modérateur Delphi

    Le guide du bon forumeur :
    __________
    Rayek World : Youtube Facebook

  4. #4
    Membre régulier
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Octobre 2006
    Messages
    127
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 127
    Points : 74
    Points
    74
    Par défaut
    Bonjour

    Les TField n'ont rien à voir avec les unités ADO, Le BDE et IB utilisent aussi l'unité Db qui contient ces TField
    Pourtant il me semble que cela a tout e même un peu a voir avec ADO dans l'unité ADOdb on voit que l'objet CustomADODataset redefini la méthode GetStateFieldValue comme ci desous
    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
     
    function TCustomADODataSet.GetStateFieldValue(State: TDataSetState;
      Field: TField): Variant;
    begin
      if IsEmpty or not (Self.State in [dsBrowse, dsEdit]) then
        Result := Null
      else
      begin
        UpdateCursorPos;
        case State of
          dsOldValue:
            Result := Recordset.Fields[Field.FieldNo-1].OriginalValue;
          dsCurValue:
            Result := Recordset.Fields[Field.FieldNo-1].UnderlyingValue;
        else
          Result := inherited GetStateFieldValue(State, Field);
        end;
      end;
    end;
    Il me semble que mon problème vient plutot du fait que il faut utiliser
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MaQuery.Recordset.resync(1,1)
    avant d'accèder à ces propriétés comme le montre JM Rabilloud dans sa doc sur ADO paragraphe
    Similaire au moteur de curseur
    mais pour l'instant je bloque sur ce resync car j'utilise une vue ou des procedures stockées comme source de mes ADOQuery, bizarement j'y parviens bien avec les PS avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
      AdoQuery1.Properties['Unique Table'].value := 'T_DEVPART_DPT';
      AdoQuery1.Recordset.Properties['Resync Command'].Value := 'EXEC Usp_Dev_Get_Devpart_Princ_Resync ?';
    mais pas avec les vues
    Bruno Petit

  5. #5
    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
    Citation Envoyé par PickEpique Voir le message
    Pourtant il me semble que cela a tout e même un peu a voir avec ADO dans l'unité ADOdb on voit que l'objet CustomADODataset redefini la méthode GetStateFieldValue comme ci desous
    Quel rapport avec le problème "Operation de variant incorrecte" et Ado ??


    Citation Envoyé par PickEpique Voir le message
    Il me semble que mon problème vient plutot du fait que il faut utiliser
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MaQuery.Recordset.resync(1,1)
    avant d'accèder à ces propriétés comme le montre JM Rabilloud dans sa doc sur ADO paragraphe

    mais pour l'instant je bloque sur ce resync car j'utilise une vue ou des procedures stockées comme source de mes ADOQuery, bizarement j'y parviens bien avec les PS avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
      AdoQuery1.Properties['Unique Table'].value := 'T_DEVPART_DPT';
      AdoQuery1.Recordset.Properties['Resync Command'].Value := 'EXEC Usp_Dev_Get_Devpart_Princ_Resync ?';
    mais pas avec les vues
    Euh ... désoler mais la, je ne comprend pas du tout le rapport avec la question de base

    Le problème du départ était un problème avec des variants (le message est quand même assez explicite : "Operation de variant incorrecte") et rien d'autres (Ado, Resync, Les vues n'ont rien à y voir).
    Modérateur Delphi

    Le guide du bon forumeur :
    __________
    Rayek World : Youtube Facebook

  6. #6
    Membre régulier
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Octobre 2006
    Messages
    127
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 127
    Points : 74
    Points
    74
    Par défaut
    Reprise de mon problème un peu tard (je bosse la dessus par bribes) ;mais donc effectivement la méthode d'accès à Oldvalue d'un objet TField appelle la méthode GetStateFieldValue qui accède à son tour à la propriété OriginalValue de l'objet Field de la collection TFields du recordset.
    Donc ici sur l'accès par TField.Oldvalue ou TField.Curvalue
    J'ai une erreur "Operation de variant incorrecte" sur tout les champs de type TBCDField; quand je les supprime (du select) j'ai une autre erreur "L'application utilise une valeur d'un typz incorrect pour l'opération en cours" sur un champ de type TStringfield (VARCHAR(24)) alors que cela passe sur un champ précédant de même type et la je sèche complètement
    avez vous une piste de recherche ?
    Bruno Petit

  7. #7
    Membre régulier
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Octobre 2006
    Messages
    127
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 127
    Points : 74
    Points
    74
    Par défaut
    je pousuis
    la 2 eme erreur est résolu c'était un autre problème
    il me reste l'erreur sur les TBCDField (numeric(18,2))
    sur Curvalue ou oLdValue et sur des champs TBCDField
    vartype me renvoie un type 14
    varTypeAsText me renvoie "Decimal"
    et dans ce cas VarSamevalue ou la comparaison directe renvoie l'erreur
    Bruno Petit

  8. #8
    Membre régulier
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Octobre 2006
    Messages
    127
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 127
    Points : 74
    Points
    74
    Par défaut
    Donc c'est finalement un problème de VarType 14
    non supporté par Delphi, comme on peux le voir dans l'unité system
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    //varDecimal  = $000E; { vt_decimal     14 } {UNSUPPORTED as of v6.x code base}
    Delphi utilise un Type Currency pour gérer les champs de type TBCDField cela est connu, mais le support de Curvalue, OLdvalue pour ce type semble être passé à la trappe, tout semble bien se passer si l'on utilise pas ces propriétés
    Donc j'ai le choix entre
    - Passer toutes les valeurs TBCDField en paramètres de ma commande de modification qu'elles aient été modifiées ou non, en utilisant Field.value
    - Passer à des types Float (SQL) -> TFloatField (Del)
    - Utiliser une vue avec un TRIGGER INSTEAD OF plutot que un BatchUpdate et des commandes paramétrées coté client
    Vous voyez d'autres possibilités ?
    Bruno Petit

  9. #9
    Membre régulier
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Octobre 2006
    Messages
    127
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 127
    Points : 74
    Points
    74
    Par défaut
    il y a aussi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    if Currency(f.Oldvalue) <> Currency(f.CurValue) then
    begin
    end;
    qui marche
    Bruno Petit

Discussions similaires

  1. Voir de l'Unicode mémorisé dans un TField
    Par der§en dans le forum Bases de données
    Réponses: 1
    Dernier message: 27/09/2006, 19h06
  2. [VBA][DEB] utilisation de oldValue
    Par ip203 dans le forum Access
    Réponses: 4
    Dernier message: 27/03/2006, 17h12
  3. construite un TFIELDS
    Par richard038 dans le forum Langage
    Réponses: 2
    Dernier message: 20/02/2006, 15h55
  4. [D7] Obtenir le premier caractère d'un TField
    Par plante20100 dans le forum Langage
    Réponses: 6
    Dernier message: 18/10/2005, 14h05
  5. Bug sur la prorpiété required d'un TField avec ADO ???
    Par denrette dans le forum Bases de données
    Réponses: 6
    Dernier message: 04/11/2003, 11h04

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