Numéro d'article: 189657 - Dernière mise à jour: mardi 13 juillet 2004 - Version: 1.4

Comment faire pour utiliser la commande ADO SHAPE

A noterCet article s'applique à un système d'exploitation différent de celui que vous utilisez. Le contenu de l'article qui ne vous concerne peut-être pas est désactivé.

Sommaire

Agrandir tout | Réduire tout

Résumé

Cet article décrit la syntaxe de commande ADO SHAPE de production de jeux d'enregistrements hiérarchiques et explique comment parcourir les jeux d'enregistrements hiérarchiques. Exemple de code VBA est également fourni.

Plus d'informations

Lorsque vous avez besoin d'accéder aux données récapitulatives et parent-enfant, vous pouvez utiliser les jeux d'enregistrements hiérarchiques comme alternative à la syntaxe JOIN et GROUP BY.

Jeux d'enregistrements hiérarchiques est utilisés dans de nombreux produits : Xbase produits utilisez la commande SET RELATION, Access utilise «Segmented Tables virtuelles» en interne pour les rapports avec des niveaux de regroupement et ainsi de suite. Hiérarchies vous permettent de générer un ou plusieurs jeux d'enregistrements, définissez les groupes et spécifiez agrégation calculs sur les jeux d'enregistrements enfants. Bien que vous pouvez implémenter une fonctionnalité similaire à l'aide de code, cette fonctionnalité majeure des tâches courantes déplace de la part du développeur sur le système.

Jeux d'enregistrements hiérarchique est disponibles via le fournisseur MSDataShape, qui est implémenté par le moteur du curseur client.

Jeux d'enregistrements hiérarchiques différence des instructions SQL JOIN et GROUP BY dans le sens avec une jointure, les champs de la table parent et le champs de la table enfant sont représentés dans le même jeu d'enregistrements. Avec un jeu d'enregistrements hiérarchique, le jeu d'enregistrements contient uniquement les champs de la table parent. En outre, le jeu d'enregistrements contient un champ supplémentaire qui représente les données enfants connexes que vous pouvez affecter à une deuxième variable de jeu d'enregistrements et Parcourir.

Lorsque vous effectuez des fonctions d'agrégation à l'aide de GROUP BY et opérateurs d'agrégation, uniquement les valeurs agrégées s'affichent dans le jeu d'enregistrements. Avec les jeux d'enregistrements hiérarchiques, les valeurs agrégées sont représentés dans le jeu d'enregistrements parent et les enregistrements de détail se trouvent dans le jeu d'enregistrements enfant.

Vous pouvez créer trois types de formes, et chaque type possède ses propres points forts et faiblesses. Vous devez choisir le mécanisme de mieux adapté aux besoins de votre application et de l'environnement que vous exécuterez votre application. Les types de forme sont les suivantes :
  • Relation basée
  • Paramètre basé
  • Groupe basé sur
Les deux premiers sont semblables dans la mesure où elles produisent une hiérarchie qui serait sinon représentée par une instruction SQL JOIN. Ils diffèrent dans la mesure où tous les enregistrements parent et enfant sont lus dans un cache local avant toute transformation continue dans la hiérarchie de relation. Ce type de hiérarchie a une surcharge initiale élevée lors de la récupération des enregistrements, mais la surcharge est faible après l'extraction initiale.

Initialement, hiérarchies basées sur des paramètres lire les enregistrements parent uniquement et extraire des enregistrements de l'enfant à la demande. Bien que la charge initiale est réduite, vous devez émettre une nouvelle requête enfant pour chaque enregistrement de parent est accessible et vous devez assurer la connexion à la source de données tant que le jeu d'enregistrements est ouvert.

La hiérarchie basée sur le groupe est équivalente à la production d'une instruction SQL agrégation jointe à un détail SQL instruction ou exécuter des fonctions d'agrégation sur les données non-normalized. Vous ne pouvez pas mettre à jour les colonnes de synthèse et les colonnes calculées car ils peuvent être dérivées de plusieurs enregistrements. Comme les hiérarchies de relation, tous les enregistrements doivent être lues en amont.

Jeux d'enregistrements hiérarchiques est mis à disposition par la clause de SHAPE. Syntaxe simplifiée est fournie en premier lieu, puis exemples avec les diagrammes. Car la syntaxe de la forme peut être assez complexe, la grammaire formelle pour la forme clause est fourni à la fin de l'article pour vous permettent d'étendre les exemples. Vous pouvez également utiliser le programme à la fin de cet article pour tester vos propres instructions SHAPE. Les exemples utilisent des tables à partir de la base de données exemple Northwind.

Syntaxe simplifiée

   SHAPE {parent-statement}
   APPEND Aggregate
        | ({child-statement} [As Alias]
          RELATE parent-field TO child-field | parameter-marker
                 [, parent-field TO child-field | parameter-marker ...])
          [, Aggregate | ({child statement})...]

   SHAPE {non-normalized-statement} [AS Alias]
   COMPUTE Aggregate
         | Alias
         | ({child-statement} [As Alias] RELATE parent-field TO
                                        child-field | parameter-marker)
           [, Aggregate | Alias | ({child-statement}...)]
   [BY grouping-field [, grouping-field]]

   SHAPE {non-normalized-statement} [AS Alias]
   BY grouping-field [, grouping-field]
				

NOTES :

  1. Si vous sélectionnez des champs portant le même nom à partir de tables différentes, il se peut que vous deviez alias pour vous assurer que l'Analyseur de SHAPE fonctionne.
  2. Les fonctions SHAPE APPEND de la même façon pour un OUTER JOIN dans la mesure où un enregistrement parent est renvoyé, même si aucun enregistrement enfant n'existe pour celui-ci.
  3. Agrégats peuvent uniquement fonctionner sur des champs dans les enfants immédiats du jeu d'enregistrements. Pour fonctionner sur les champs de petits-enfants, etc., vous devez produire des agrégats intermédiaires. Reportez-vous à la hiérarchie de groupe à l'aide de Aggregate exemple à la fin de cet article pour une illustration.
  4. Si vous utilisez une fonction d'agrégation avec la syntaxe SHAPE APPEND, la valeur d'agrégation occupera un champ ajouté le jeu de résultats parent qui contient également les champs à partir de l'instruction de parent. En revanche, Le SHAPE COMPUTE et SHAPE BY créer un nouveau niveau parent pour les agrégats et la non-normalisé-instruction qui devient le jeu d'enregistrements enfant.
  5. Le fournisseur SHAPE requiert que vous incluez des alias pour la non normalisées-instruction dans la clause COMPUTE lorsque vous utilisez SHAPE COMPUTE. Si vous ne le faites pas, cela entraîne un message que la fonctionnalité n'est pas prise en charge, bien qu'il ne provoque une erreur de syntaxe.

Exemples

Hiérarchie de relation simple :

   SHAPE  {select * from customers}
   APPEND ({select * from orders} AS rsOrders
           RELATE customerid TO customerid)
				
les rendements :
   Customers.*
   rsOrders
        |
        +----Orders.*
				
dans le diagramme précédent, le jeu d'enregistrements parent contient tous les champs de la table Customers et un champ appelé rsOrders. rsOrders fournit une référence au jeu d'enregistrements enfant et contient tous les champs provenant des ordres des table. Les autres exemples utilisent une notation similaire.

Hiérarchie paramétrée :

   SHAPE  {select * from customers}
   APPEND ({select * from orders where customerid = ?} AS rsOrders
           RELATE customerid TO PARAMETER 0)
				
Cela se traduit par la même hiérarchie que la hiérarchie de relation simple.

Composés de hiérarchie de relation :

Cet exemple illustre une hiérarchie à trois niveaux de clients, commandes et détails de commande :
   SHAPE  {SELECT * from customers}
   APPEND ((SHAPE  {select * from orders}
            APPEND ({select * from [order details]} AS rsDetails
                   RELATE orderid TO orderid)) AS rsOrders
          RELATE customerid TO customerid)
				
les rendements :
   Customers.*
   rsOrders
        |
        +----Orders.*
             rsDetails
                 |
                 +----[Order Details].*
				

Hiérarchie de relation multiples :

Cet exemple illustre une hiérarchie impliquant un jeu d'enregistrements parent et deux jeux d'enregistrements enfant, dont est paramétrée :
   SHAPE  {SELECT * FROM customers}
   APPEND ({SELECT *
            FROM orders
            WHERE orderdate < #1/1/1998# AND customerid = ?}
            RELATE customerid TO PARAMETER 0) AS rsOldOrders,
          ({SELECT *
            FROM orders
            WHERE orderdate >= #1/1/1998#}
            RELATE customerid TO customerid) AS rsRecentOrders
				
les rendements :
   Customers.*
   rsOldOrders
        |
        +----Orders.*
   rsRecentOrders
        |
        +----Orders.*
				

Hiérarchie avec la fonction d'agrégation :

   SHAPE  (select * from orders}
   APPEND ({select od.orderid, od.UnitPrice * od.quantity as ExtendedPrice
            from [order details] As od}
          RELATE orderid TO orderid) As rsDetails,
          SUM(ExtendedPrice) AS OrderTotal
				
les rendements :
   Orders.*
   rsDetails
       |
       +----orderid
            ExtendedPrice
   OrderTotal
				

Hiérarchie de groupe :

   SHAPE  {select customers.customerid AS cust_id, orders.*
           from customers inner join orders
           on customers.customerid = orders.customerid} AS rsOrders
   COMPUTE rsOrders BY cust_id
				
les rendements :
   rsOrders
       |
       +----cust_id
            Orders.*
   cust_id
				

Hiérarchie de groupe avec la fonction d'agrégation :

Remarque : la clause interne SHAPE dans cet exemple est identique à l'instruction utilisée dans la hiérarchie à l'aide exemple Aggregate.
   SHAPE
           (SHAPE   {select customers.*, orders.orderid, orders.orderdate
                     from customers inner join orders
                     on customers.customerid = orders.customerid}
            APPEND  ({select od.orderid,
                             od.unitprice * od.quantity as ExtendedPrice
                      from [order details] as od} AS rsDetails
                    RELATE orderid TO orderid),
                    SUM(rsDetails.ExtendedPrice) AS OrderTotal) AS rsOrders
   COMPUTE  rsOrders,
            SUM(rsOrders.OrderTotal) AS CustTotal,
            ANY(rsOrders.contactname) AS Contact
   BY       customerid
				
which yields:
   rsOrders
        |
        +----Customers.*
             orderid
             orderdate
             rsDetails
                  |
                  +----orderid
                       ExtendedPrice
             OrderTotal
   CustomerTotal
   Contact
   customerid
				

Regroupements multiples :

   SHAPE
          (SHAPE  {select customers.*,
                          od.unitprice * od.quantity as ExtendedPrice
                   from (customers inner join orders
                   on customers.customerid = orders.customerid) inner join
                   [order details] as od on orders.orderid = od.orderid}
                          AS rsDetail
           COMPUTE ANY(rsDetail.contactname) AS Contact,
                   ANY(rsDetail.region) AS Region,
                   SUM(rsDetail.ExtendedPrice) AS CustTotal,
                   rsDetail
           BY customerid) AS rsCustSummary
   COMPUTE rsCustSummary
   BY      Region
				
les rendements :
   rsCustSummary
        |
        +-----Contact
              Region
              CustTotal
              rsDetail
                   |
                   +----Customers.*
                        ExtendedPrice
              customerid
   Region
				

Total général :

   SHAPE
          (SHAPE  {select customers.*,
                          od.unitprice * od.quantity as ExtendedPrice
                   from (customers inner join orders
                   on customers.customerid = orders.customerid) inner join
                   [order details] as od on orders.orderid = od.orderid}
                          AS rsDetail
           COMPUTE ANY(rsDetail.contactname) AS Contact,
                   SUM(rsDetail.ExtendedPrice) AS CustTotal,
                   rsDetail
           BY customerid) AS rsCustSummary
   COMPUTE SUM(rsCustSummary.CustTotal) As GrandTotal,
           rsCustSummary
				
Notez la clause BY manquante dans le résumé externe. Cette valeur définit le total général car l'ensemble de lignes parent contient un seul enregistrement avec le total général et un pointeur vers le jeu d'enregistrements enfant.
   GrandTotal
   rsCustSummary
        |
        +-----Contact
              CustTotal
              rsDetail
                  |
                  +----Customers.*
                       ExtendedPrice
              customerid
				

Hiérarchie complexe :

Cet exemple illustre une hiérarchie qui contient un ensemble de lignes parent, deux jeux de lignes enfant, dont est paramétrée, et un détail de groupe.
   SHAPE {select customers.* from customers} AS rsDetail
   COMPUTE rsDetail,
           ANY(rsDetail.companyname) AS Company,
           ({select * from orders where customerid = ?}
                   RELATE customerid TO PARAMETER 0) AS rsOrders,
           COUNT(rsOrders.orderid) AS OrderCount
   BY customerid
				
which yields:
rsDetail
        |
        +----Customers.*
   Company
   rsOrders
        |
        +----Orders.*
   OrderCount
   customerid
				

Parent groupée concernant enfant groupé :

   SHAPE
          (SHAPE  {select * from customers}
           APPEND ((SHAPE {select orders.*, year(orderdate) as OrderYear,
                                  month(orderdate) as OrderMonth
                           from orders} AS rsOrders
                    COMPUTE rsOrders
                    BY customerid, OrderYear, OrderMonth)
                    RELATE customerid TO customerid) AS rsOrdByMonth )
           AS rsCustomers
   COMPUTE rsCustomers
   BY      region
				
les rendements :
   rsCustomers
        |
        +-----customers.*
              rsOrdByMonth
                 |
                 +-----rsOrders
                            |
                            +---- Orders.*
                       customerid
                       OrderYear
                       OrderMonth
   region
				

Grammaire formelle clause SHAPE

  <shape-command>      ::=  SHAPE <table-exp> [AS <alias>]
                            [<shape_action>]

  <shape-action>       ::=  APPEND <aliased-field-list>
                            | COMPUTE <aliased-field-list>
                              [BY <field-list>]
                            | BY <field-list>

  <table-exp>          ::=  {<native-sql-statement>}
                            | ( <shape-command> )
 
  <aliased-field-list> ::=  <aliased-field> [, <aliased-field...]
 
  <aliased-field>      ::=  <field-exp> [AS <alias>]
 
  <field-exp>          ::=  ( <relation-exp> ) | <calculated-exp>
 
  <relation_exp>       ::=   <table-exp> [AS <alias>] RELATE
                             <relation-cond-list>
 
  <relation-cond-list> ::=   <relation-cond> [, <relation-cond>...]
 
  <relation-cond>      ::=   <field-name> TO <child-ref>
 
  <child-ref>          ::=   <field-name> | PARAMETER <param-ref>
 
  <param-ref>          ::=   <name> | <number>
 
  <field-list>         ::=   <field-name [, <filed-name>]
 
  <calculated-exp>     ::=   SUM (<qualified-field-name>)
                             | AVG (<qualified-field-name>)
                             | MIN (<qualified-field-name>)
                             | MAX (<qualified-field-name>)
                             | COUNT (<alias>)
                             | SDEV (<qualified-field-name>)
                             | ANY (<qualified-field-name>)
                             | CALC (<expression>)
 
  <qualified-field-name>::=  <alias>.<field-name> | <field-name>
 
  <alias>               ::=  <quoted-name>
 
  <field-name>          ::=  <quoted-name>
 
  <quoted-name>         ::=  "<string>" | '<string>' | <name>
 
  <name>                ::=  alpha [ alpha | digit | _ | # ...]
 
  <number>              ::=  digit [digit...]
 
  <string>              ::=  unicode-char [unicode-char...]
 
  <expression>          ::=  an expression recognized by the Jet
                             Expression service whose operands are
                             other non-CALC columns in the same row.
				

Programme de test de SHAPE VBA

Le code de programme VBA suivant permet de frappe dans votre propre commande SHAPE et afficher la hiérarchie de champ ou indiquer l'emplacement de l'erreur de syntaxe.

Avertissement : utilisation du CODE fourni au PRESENT ARTICLE AT vos propres risques. Microsoft fournit ce code «tel quel» sans garantie d'aucune sorte, expresse ou implicite, y compris, de manière non limitative les garanties implicites de qualité marchande et/ou d'adéquation à un usage particulier.
  1. Dans l'administrateur ODBC du Panneau de configuration, ajoutez un DSN pour le pilote ODBC Microsoft Access 97 appelé OLE_DB_NWIND_JET pointant vers la base de données Northwind (ou NWIND).
  2. Créez un nouveau projet. Ajoutez deux zones de texte (Text1 et Text2) et un bouton de commande (Command1).
  3. Vérifiez les deux zones de texte soit suffisamment grande pour afficher plusieurs lignes de texte et définissez les propriétés suivantes :
          Multiline: True                (Visual Basic only)
          Scrollbars: Vertical
          Font: Courier New 10 Point
    					
  4. Dans le menu projet, choisissez références et ajoutez une référence à Microsoft ActiveX Data Objects Library.
  5. Ajoutez le code suivant :
       Private Sub Command1_Click()
       Dim cn As ADODB.Connection, rs As ADODB.Recordset
         Me!Text2.Text = ""
         Set cn = New ADODB.Connection
         Set rs = New ADODB.Recordset
         cn.Provider = "MSDataShape"
         cn.Open "dsn=OLE_DB_NWIND_JET"
         On Error Resume Next
         rs.Open Me!Text1.Text, cn, adOpenStatic, adLockReadOnly, adCmdText
         If Err Then MsgBox Error
         ListChapteredFields rs, 0
         rs.Close
         cn.Close
         Set rs = Nothing
         Set cn = Nothing
       End Sub
    
       Private Sub LogText(ByVal sLine As String)
         If Me!Text2.Text = "" Then
           Me!Text2.Text = sLine
         Else
           Me!Text2.Text = Me!Text2.Text & vbCrLf & sLine
         End If
       End Sub
    
       Private Sub ListChapteredFields(ByVal rs As ADODB.Recordset, _
                                          ByVal Level As Long)
       Dim I As Long
         For I = 0 To rs.Fields.Count - 1
           LogText Space$(Level * 3) & rs(I).Name
           If rs(I).Type = adChapter Then
             ListChapteredFields rs(I).Value, Level + 1
           End If
         Next I
       End Sub
    					
  6. Exécutez le projet. Tapez la commande SHAPE dans Texte1, cliquez sur le bouton de commande et la hiérarchie s'affiche dans Texte2.
Remarque : le texte suivant fournit un exemple d'utilisation le fournisseur Microsoft Jet OLEDB avec le fournisseur SHAPE:
  cn.Provider = "MSDataShape"
  cn.Open "Data Provider=Microsoft.Jet.OLEDB.4.0"
				
Remarque : Si vous orthographiez mal noms de champ ou de table lorsque vous utilisez le pilote ODBC de Access 97 ou JOLT fournisseurs, vous recevrez le message suivant vous :
Trop peu de paramètres. N attendu.
Autres fournisseurs risquent de produire un message différent.

Références

ADO 2.0 hiérarchiques spécification de curseur

Pour plus d'informations sur la syntaxe de SHAPE APPEND et sur la façon de parcourir les jeux d'enregistrements hiérarchiques, consultez l'article suivant dans la base de connaissances Microsoft :
185425  (http://support.microsoft.com/kb/185425/EN-US/ ) Jeux d'enregistrements hiérarchiques via SHAPE APPEND via C + ADO + / VBA/Java

Les informations contenues dans cet article s'appliquent au(x) produit(s) suivant(s):
  • Microsoft ActiveX Data Objects 2.0
  • Microsoft ActiveX Data Objects 2.1 Service Pack 2
  • Microsoft ActiveX Data Objects 2.5
  • Microsoft ActiveX Data Objects 2.6
  • Microsoft ActiveX Data Objects 2.7
Mots-clés : 
kbmt kbdatabase kbhowto kbprovider KB189657 KbMtfr
Traduction automatiqueTraduction automatique
IMPORTANT : Cet article est issu du système de traduction automatique mis au point par Microsoft (http://support.microsoft.com/gp/mtdetails). Un certain nombre d?articles obtenus par traduction automatique sont en effet mis à votre disposition en complément des articles traduits en langue française par des traducteurs professionnels. Cela vous permet d?avoir accès, dans votre propre langue, à l?ensemble des articles de la base de connaissances rédigés originellement en langue anglaise. Les articles traduits automatiquement ne sont pas toujours parfaits et peuvent comporter des erreurs de vocabulaire, de syntaxe ou de grammaire (probablement semblables aux erreurs que ferait une personne étrangère s?exprimant dans votre langue !). Néanmoins, mis à part ces imperfections, ces articles devraient suffire à vous orienter et à vous aider à résoudre votre problème. Microsoft s?efforce aussi continuellement de faire évoluer son système de traduction automatique.
La version anglaise de cet article est la suivante: 189657  (http://support.microsoft.com/kb/189657/en-us/ )
L'INFORMATION CONTENUE DANS CE DOCUMENT EST FOURNIE PAR MICROSOFT SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE. L'UTILISATEUR ASSUME LE RISQUE DE L'UTILISATION DU CONTENU DE CE DOCUMENT. CE DOCUMENT NE PEUT ETRE REVENDU OU CEDE EN ECHANGE D'UN QUELCONQUE PROFIT.
Retired KB ArticleExclusion de responsabilité concernant les contenus obsolètes dans la Base de connaissances
Cet article concerne des produits pour lesquels Microsoft n'offre plus de support. Il est par conséquent fourni « en l'état » et ne sera plus mis à jour.