IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Comprendre les Recordset ADO

Comprendre les Recordset ADO


précédentsommairesuivant

IX. Mise en forme des données

Le moteur de curseur client implémente un fournisseur de service qui permet de construire des recordset un peu particuliers, le "Data Shaping Service for OLE Db". Cette mise en forme des données peut souvent ressembler à une requête de jointure standard ou à l'utilisation d'agrégats, mais le résultat final est sensiblement différent. Je ne vais pas visiter en détails ici le langage Shape car sa syntaxe peut devenir rapidement complexe, aussi n'allons nous voir que quelques exemples. Toutefois dans le deuxième exemple nous verrons une technique de création de requête.

N.B : On peut utiliser le composant DataEnvironment pour générer des requêtes Shape.

Pour faire simple, disons qu'un recordset "Shape" est un recordset auquel on a ajouté un (des) champ(s), ce champ pouvant contenir une référence à un autre recordset, une valeur calculée sur la ligne ou sur une colonne d'un recordset, etc...

Cette mise en forme est faite par le langage Shape dont nous allons voir ici deux cas d'utilisation.

Tout d'abord, il faut spécifier deux fournisseurs à la connection, le fournisseur de service dans la propriété Provider de la connection, et le fournisseur de données dans la propriété dynamique "Data Provider" de l'objet Connection. Evidemment, on peut aussi passer les informations dans la chaîne de connexion. Ensuite l'astuce principale consiste à toujours travailler vis-à-vis du Recordset enfant (ou secondaire) pour construire le recordset.

IX-A. Recordset hiérarchique

Dans cet exemple nous allons construire un recordset hiérarchique. Ce recordset contiendra la liste de tous les auteurs, chacun de ces enregistrements contiendra la liste de tous les livres qu'ils ont écrits.

Pour affecter un recordset enfant à un recordset parent, on doit utiliser la commande Shape APPEND et préciser une clause RELATE qui permet de faire la relation entre le parent et l'enfant. Bien sur, la hiérarchie va dépendre de la structure de la base. Dans le cas de la base "biblio" je vais devoir utiliser trois tables pour construire mon recordset. Regardons le code suivant :

 
Sélectionnez
Dim cnn1 As ADODB.Connection, MonRs As ADODB.Recordset, RsLect As ADODB.Recordset
Set cnn1 = New ADODB.Connection
cnn1.CursorLocation = adUseClient
cnn1.Provider = "MSDataShape"
cnn1.Properties("Data Provider") = "Microsoft.Jet.OLEDB.4.0"
cnn1.Open "Data Source=d:\biblio.mdb"
'autre méthode d'ouverture possible
'cnn1.open "Provider = MSDataShape;Data Provider=Microsoft.Jet.OLEDB.4.0
';Data Source=d:\biblio.mdb ;User Id=Admin; Password="
Set MonRs = New ADODB.Recordset
MonRs.StayInSync = False
MonRs.Open "SHAPE {SELECT * FROM `Authors`}  AS cmdMere APPEND (( SHAPE {SELECT * FROM `Title Author`}
	  AS cmdFille APPEND ({SELECT * FROM `Titles`}  
	  AS cmdPetFille RELATE 'ISBN' TO 'ISBN')  
  	 AS cmdPetFille) AS cmdFille RELATE 'Au_ID' TO 'Au_ID') AS cmdFille", cnn1
'possibilité d'utiliser une grille hierarchique pour visualiser le résultat
'Set MSHFlexGrid1.DataSource = MonRs
Set RsLect = New ADODB.Recordset
Set RsLect = MonRs("cmdFille").Value
Set RsLect = RsLect("cmdPetFille").Value

Dans ce cas je crée une relation composée avec ma commande Shape, ce qui revient à dire que mon recordset est composé de trois Recordset. Pour pouvoir lire les données de la table "Titles", je crée un recordset pour aller récupérer le recordset renvoyé par l'alias "cmdPetFille". Comme vous le voyez, rien de bien sorcier.

IX-B. Agrégat

Les agrégats réalisés par la commande SHAPE sont sensiblement les mêmes que ceux réalisés à l'aide du SQL.

Dans cet exemple nous allons voir comment construire sans se tromper une commande Shape. L'objectif est de récupérer le nom de l'auteur et le nombre de livre qu'il a écrit. Ceci peut ressembler à l'exécution de la requête SQL suivante :

 
Sélectionnez
SELECT Authors.Author, Count([Title Author].ISBN) AS NbLivre
FROM Authors 
	      INNER JOIN [Title Author] 
		      ON Authors.Au_ID = [Title Author].Au_ID
GROUP BY Authors.Author;

Mais il y a une différence. Avec ma commande Shape je garde la possibilité d'accéder à la valeur du champ 'ISBN' ce que ne me permet pas la requête ci-dessus. Nous allons utiliser le code suivant :

 
Sélectionnez
Dim cnn1 As ADODB.Connection, MonRs As ADODB.Recordset, RsLect As ADODB.Recordset

Set cnn1 = New ADODB.Connection
cnn1.open "Provider = MSDataShape;Data Provider=Microsoft.Jet.OLEDB.4.0;Data Source=d:\biblio.mdb ;User Id=Admin; Password="
Set MonRs = New ADODB.Recordset
MonRs.StayInSync = False
MonRs.Open " SHAPE {SELECT * FROM `Authors`}  
	AS cmdAuthor APPEND (( SHAPE {SELECT * FROM `Title Author`}  
	AS cmdFille COMPUTE cmdFille, COUNT(cmdFille.'ISBN') 
	AS AgrISBN BY 'Au_ID') AS cmdGrISBN RELATE 'Au_ID' TO 'Au_ID') AS cmdGrISBN", cnn1
Set RsLect = New ADODB.Recordset
Set RsLect = MonRs("cmdGrISBN").Value
'affiche la valeur du compte de livre du premier enregistrement
Debug.Print RsLect!AgrISBN
Set RsLect = RsLect("cmdFille").Value
'affiche la valeur ISBN du premier enregistrement
Debug.Print RsLect!ISBN

Le code n'a rien de bien complexe aussi ne vais-je pas entrer dans le détail, par contre nous allons étudier la commande SHAPE.

Pour mieux comprendre regardons là écrite ainsi :

SHAPE {SELECT * FROM `Authors`} AS cmdAuthor APPEND ( ( SHAPE {SELECT * FROM `Title Author`} AS cmdFille COMPUTE cmdFille, COUNT(cmdFille.'ISBN') AS AgrISBN BY 'Au_ID') AS cmdGrISBN RELATE 'Au_ID' TO 'Au_ID') AS cmdGrISBN

Les règles de base sont la suivante

SHAPE est toujours lié avec un APPEND ou un COMPUTE. Il devra donc y avoir autant de fois SHAPE dans la commande que l'on trouvera de fois les termes Append et COMPUTE.

Chaque commande SHAPE ajoute une colonne au recordset dans lequel il est imbriqué

Les champs des relations doivent être présents dans la commande mère et la commande fille.

Je vous ai dit au début du chapitre de raisonner plutôt du coté fils. Dans ce cas, la construction se fait de la manière suivante.

  1. Le but est d'obtenir le compte de ISBN, je construis donc l'agrégat de la forme COMPUTE Recordset1, Agrégat (Champs de l'agrégat) AS alias BY regroupement éventuel. Dans notre cas la commande en vert ou recordset1 est cmdFille.
  2. Mon recordset1 doit contenir le champ utilisé dans l'agrégat (dans notre cas 'ISBN'). Pour nous le recordset vient de la table 'Title Author'. Mon recordset1 est donc une commande SHAPE de la forme SHAPE Requête As Alias COMPUTE Agrégat AS Alias final. Notez que cette commande serait un recordset mis en forme valide si je ne souhaitais pas l'imbriquer plus avant.
  3. Mon Alias final doit contenir le champ à mettre en relation avec le recordset parent. Je n'ai pas besoin stricto sensu de cet alias intermédiaire, sauf pour des besoins de lecture. Je vais donc réutiliser le même comme alias dans le recordset parent. Je vais donc avoir SHAPE (recordset parent) AS Alias (facultatif) APPEND (Recordset imbriqué) AS Alias (facultatif) RELATE relation AS Alias

Comme je le vois j'utilise deux alias facultatif et la commande : SHAPE {SELECT * FROM `Authors`} APPEND (( SHAPE {SELECT * FROM `Title Author`} AS cmdFilleCOMPUTE cmdFille, COUNT(cmdFille.'ISBN') AS AgrISBN BY 'Au_ID' ) RELATE 'Au_ID' TO 'Au_ID') AS cmdGrISBN

Et strictement équivalente. Pour expliciter mieux ce que nous obtenons, visualisons la structure.

Image non disponible

Mon recordset final est donc composé de trois recordset.


précédentsommairesuivant

Copyright © 2003 bidou. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.