DateSetProvider upWhereKeyOnly, erreur : Unable to find record No Key specified

jderf
Messages postés
189
Date d'inscription
mercredi 29 décembre 2004
Statut
Membre
Dernière intervention
2 octobre 2014
- 19 sept. 2012 à 11:18
jderf
Messages postés
189
Date d'inscription
mercredi 29 décembre 2004
Statut
Membre
Dernière intervention
2 octobre 2014
- 9 oct. 2012 à 10:28
Bonjour,

J'utilise la chaine TSQLQuery -> TDataSetprovider -> TclientDataSet -> TDataSource -> TdataControl

J'ai une requête qui remonte un seul enregistrement, composée de plusieurs champs. A la lecture, les datacontrol affichent correctement les valeurs de ces champs.
Voici la requête :

SQuery_General_visite.SQL.Add('Select no_dossier, libelle_visite from visite where id_visite=''' + Visite.id_visite + '''');
id_visite est la clé primaire de la table visite.


La mise à jour se fait par :
ClientDS_General_visite.Post;
ClientDS_General_visite.ApplyUpdates(-1);

La mise à jour fonctionne correctement uniquement avec l'option UpWhereAll.

Voici donc mon problème :
Pour faire plus « propre », je souhaite utiliser la clé primaire de la table pour faire les mises à jour, donc l'option upWhereKeyOnly.

J'adapte donc la requête :

SQuery_General_visite.SQL.Add('Select id_visite, no_dossier, libelle_visite from visite where id_visite=''' + Visite.id_visite + '''');

J'indique quelle est la clé primaire

SQuery_General_visite.FieldByName('id_visite').ProviderFlags := [pfInKey];

et modifie l'UpdateMode
DSprovider_General_visite.UpdateMode := upWhereKeyOnly;

Mais j'obtiens, alors l'erreur suivante lors des mises à jour "Unable to find record No Key specified"
Pourtant l'ensemble de donnée, ne contient qu'un seul enregistrement avec trois champs, id_visite, no_dossier et libelle_visite. Je ne comprends pas pourquoi le DataSetProvider, ne trouve pas la Key ?

Merci, pour votre aide

Jean

4 réponses

cs_MAURICIO
Messages postés
2106
Date d'inscription
mardi 10 décembre 2002
Statut
Modérateur
Dernière intervention
15 décembre 2014
5
20 sept. 2012 à 10:59
Salut Jean,

j' ai moi même un peu galéré au départ.
La propriété ProviderFlags doit être atribuée au ClientDataset!

Méthode:
1 ) DSprovider_General_visite.UpdateMode := upWhereKeyOnly;
2 ) Ouvrir le query afin de récupérer les champs
3 ) SQuery_General_visite.FieldByName('id_visite').ProviderFlags := [pfInKey];
Pour que les Insert fonctionnent : SQuery_General_visite.FieldByName('id_visite').Required := false;
4 ) Ouvrir le ClientDataset: les champs vont hériter des mêmes définitions (Required + ProviderFlags) du query.

Voilà, tu peux aussi faire cela en Design time.

A+


Composants Cindy pour Delphi
Faites une donation.
0
jderf
Messages postés
189
Date d'inscription
mercredi 29 décembre 2004
Statut
Membre
Dernière intervention
2 octobre 2014
1
26 sept. 2012 à 11:42
Bonjour Mauricio,

Merci pour ta réponse. Je la testerai à l'occasion.

Ma requête définitive contient plusieurs jointures avec des tables, de nombreux champs sont quand lecture.
Lorsque j'ai vu la diificulté pour controler l'update du ClientDataSet, j'ai fait le choix d'ecrire ma requête d'update dans l'événement BeforeUpdateRecord (avec Applied := True;). Comme cela je maitrise exactement les champs que je renvois sur la base.

Bonne journée.

Jean
0
jderf
Messages postés
189
Date d'inscription
mercredi 29 décembre 2004
Statut
Membre
Dernière intervention
2 octobre 2014
1
4 oct. 2012 à 21:02
Bonsoir Mauricio,

Je viens de tester et malheuresement ça ne marche pas chez moi.

J'ai fait un nouveau projet de test, tout simple.
Une base simple, 1 seul table "personnes" avec 3 champs "id_per", "nom_per", et "prenom_per"

La chaine TSQLConnexion -> TSQLQuery -> TDataSetprovider -> TclientDataSet -> TDataSource -> TdataControl

Sur la form, un DBgrid et un DBNavigator

A l'execution, les valeus s'affiche normalement.
Je clique sur le "+" pour insert, une fois les valeurs saisies, sur le "V" pour post et j'ai l'erreur "Field 'id_per' must have a value"

Voici le code :

procedure TFrmPersonne.FormCreate(Sender: TObject);
begin
  // 1
  DSprovider_personne.UpdateMode := upWhereKeyOnly;

  // 2
  SQLQuery_Personne.SQL.Clear;
  SQLQuery_Personne.SQL.Add('Select nom_per, prenom_per, id_per from personnes');
  SQLQuery_Personne.Open;

  // 3
  SQLQuery_Personne.FieldByName('id_per').ProviderFlags := [pfInKey];
  SQLQuery_Personne.FieldByName('id_per').Required := false;

  // 4
  ClientDS_personne.Open;  // ERREUR : Field 'id_per' must have à value

  DBGrid_personne.Columns[2].Visible := false //masque la colonne de id_per dans le DBGrid
end;



Merci pour ton aide, car je bloque un peu !

Jean
0
jderf
Messages postés
189
Date d'inscription
mercredi 29 décembre 2004
Statut
Membre
Dernière intervention
2 octobre 2014
1
9 oct. 2012 à 10:28
Bonjour,

Finalement après de nombreux tests et lectures sur le web, j'ai pas trouvé de solution.
Je crois que c'est un problème de compatibilité entre D7 (build 4.453), mysql 5.1.35. Cela provient sans doute des DLL utilisées dans la TSQLconnetion (LibraryName et VendorLib)
Dans mon cas j'utilise dbxopenmysql50.dll (156ko) et libmysql.dll (2160ko).

Si quelqu'un utilise avec succès dbExpress avec D7, mysql 5, ce serait sympa de me préciser les taille et nom de leur DLL.

Merci.
Jean
0