Artigo: 189657 - Última revisão: terça-feira, 13 de Julho de 2004 - Revisão: 1.4

Como utilizar o comando ' SHAPE ADO

Dica do SistemaEste artigo aplica-se a um sistema operativo diferente do que está a utilizar. Foi desactivado o conteúdo do artigo, que pode não ser relevante para si.

Nesta página

Expandir tudo | Reduzir tudo

Sumário

Este artigo descreve a sintaxe do comando ADO SHAPE para produzir conjuntos de registos hierárquicos e explica como atravessar conjuntos de registos hierárquicos. Exemplo de código VBA também é fornecido.

Mais Informação

Pode utilizar conjuntos de registos hierárquicos como alternativa à sintaxe JOIN e GROUP BY quando precisar de aceder principal-subordinado e dados de sumário.

Conjuntos de registos hierárquicos são utilizados em vários produtos: Xbase produtos utilize o comando SET RELATION, Access utiliza "Segmentadas tabelas virtuais" internamente para relatórios com níveis de agrupamento e assim sucessivamente. Hierarquias permitem-lhe para criar um ou vários conjuntos de registos, definir agrupamentos e especificar agregação cálculos sobre conjuntos de registos subordinados. Apesar de pode implementar funcionalidades similares através de código, esta funcionalidade muda grande parte do trabalho mundano do programador para o efeito ao sistema.

Conjuntos de registos hierárquicos estão disponíveis através do fornecedor de MSDataShape, é implementado pelo motor do cursor de cliente.

Conjuntos de registos hierárquicos diferem das instruções SQL JOIN e GROUP BY que com uma é JOIN , de campos da tabela principal e a campos da tabela subordinada são representados no conjunto de registos mesmo. Com um conjunto de registos hierárquico, o conjunto de registos contém apenas os campos da tabela principal. Além disso, o conjunto de registos contém um campo adicional que representa os dados relacionados subordinados, que pode atribuir a uma segunda variável do conjunto de registos e atravessar.

Quando estiver a efectuar funções de agregação utilizando GROUP BY e operadores de agregação, apenas os valores agregados aparecem no conjunto de registos. Com conjuntos de registos hierárquicos, os valores agregados são representados no conjunto de registos principal e os registos de detalhe estão no conjunto de registos subordinado.

Pode criar três tipos de formas e cada tipo tem as suas próprias pontos fortes e fracos. Tem de escolher o mecanismo que melhor se adequa as necessidades da sua aplicação e o ambiente que vai executar a aplicação num. Os tipos de SHAPE são:
  • Relação baseada em
  • Com o parâmetro
  • Grupo com base
Os dois primeiros são semelhantes podem produzem uma hierarquia que caso contrário, seria representada por uma instrução SQL JOIN . Diferem em que todos os registos principais e subordinados são lidos para uma cache local antes de qualquer processamento continua na hierarquia baseada em relação. Este tipo de hierarquia tem um alto custo inicial ao obter os registos, mas a sobrecarga é pouco depois da obtenção inicial.

Inicialmente, hierarquias com o parâmetro apenas ler os registos principal e obter a criança registos a pedido. Apesar da sobrecarga inicial é reduzida, tem que emitir uma nova consulta subordinados para cada registo principal que é acedido e deve manter a ligação à origem de dados para desde que o conjunto de registos é aberto.

A hierarquia baseadas em grupos é equivalente a produzir uma agregação instrução de SQL associada a um detalhe SQL instrução ou efectuar funções de agregação de dados não normalizada. Não consegue actualizar as colunas de sumário e as colunas calculadas porque pode ser derivadas de mais do que um registo. Como hierarquias baseadas em relação, todos os registos devem ser lido até à frente.

Conjuntos de registos hierárquicos são disponibilizados pela cláusula SHAPE . Sintaxe simplificado é fornecido em primeiro lugar, em seguida, exemplos com diagramas. Uma vez que a sintaxe SHAPE pode obter muito complexa, a gramática formal para o SHAPE cláusula é fornecida no final do artigo para que possa expandir os exemplos. Também pode utilizar o programa no fim deste artigo para testar as suas próprias instruções SHAPE . Os exemplos utilizam tabelas da base de dados de exemplo Adamastor.

Sintaxe simplificada

   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]
				

NOTAS:

  1. Se seleccionou nomes idêntico campos de tabelas diferentes, poderá ser necessário para o alias para assegurar que o analisador SHAPE funciona.
  2. As funções SHAPE APPEND da mesma forma para uma OUTER JOIN em que um registo principal é devolvido, mesmo se não existem registos subordinados existirem para o mesmo.
  3. Agregados apenas podem funcionar em campos os subordinados imediatos do conjunto de registos. Para funcionar em campos subordinados e assim sucessivamente, tem de produzir agregados intermédios. Ver a hierarquia de grupo com agregado exemplo no fim deste artigo para obter uma ilustração.
  4. Se utilizar uma função de agregação com a sintaxe de APPEND SHAPE , o valor agregado ocupa um campo anexado ao conjunto de resultados principal, que também contém os campos da instrução principal. Em contraste, SHAPE COMPUTE os BY SHAPE criam um novo nível principal para os agregados e o não normalizada-instrução torna-se o conjunto de registos subordinados.
  5. O fornecedor SHAPE requer que inclua alias para a não-normalizada-instrução na cláusula COMPUTE quando utilizar SHAPE COMPUTE . Não o fizer, resulta numa mensagem de que a funcionalidade não é suportada, apesar de não resulta num erro de sintaxe.

Exemplos

Hierarquia de relação simples:

   SHAPE  {select * from customers}
   APPEND ({select * from orders} AS rsOrders
           RELATE customerid TO customerid)
				
os lucros:
   Customers.*
   rsOrders
        |
        +----Orders.*
				
num diagrama anterior, o conjunto de registos principal contém todos os campos da tabela clientes e um campo denominado rsOrders. rsOrders fornece uma referência para o conjunto de registos subordinados e contém todos os campos a partir de encomendas tabela. Outros exemplos utilizam uma notação semelhante.

Hierarquia com parâmetros:

   SHAPE  {select * from customers}
   APPEND ({select * from orders where customerid = ?} AS rsOrders
           RELATE customerid TO PARAMETER 0)
				
Isto resulta na mesma hierarquia como hierarquia de relação simples.

Composto hierarquia de relação:

Este exemplo ilustra uma hierarquia de três níveis de clientes, encomendas e detalhes da encomenda:
   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)
				
os proveitos:
   Customers.*
   rsOrders
        |
        +----Orders.*
             rsDetails
                 |
                 +----[Order Details].*
				

Vários hierarquia de relação:

Este exemplo ilustra uma hierarquia que envolvem um conjunto de registos principal e dois conjuntos de registos de subordinados, um dos quais é parametrizado:
   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
				
os proveitos:
   Customers.*
   rsOldOrders
        |
        +----Orders.*
   rsRecentOrders
        |
        +----Orders.*
				

Hierarquia com agregado:

   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
				
os lucros:
   Orders.*
   rsDetails
       |
       +----orderid
            ExtendedPrice
   OrderTotal
				

Hierarquia de grupo:

   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
				
os lucros:
   rsOrders
       |
       +----cust_id
            Orders.*
   cust_id
				

Hierarquia de grupo com agregado:

Nota : A cláusula interna SHAPE neste exemplo é idêntica à instrução utilizada na hierarquia com o exemplo de agregação.
   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
				

Múltiplos agrupamentos de par:

   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
				
os lucros:
   rsCustSummary
        |
        +-----Contact
              Region
              CustTotal
              rsDetail
                   |
                   +----Customers.*
                        ExtendedPrice
              customerid
   Region
				

Total geral:

   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
				
Tenha em atenção a cláusula BY em falta no resumo externa. Isto define o total global porque o conjunto de linhas principal contém um único registo com o total global e um apontador para o conjunto de registos subordinados.
   GrandTotal
   rsCustSummary
        |
        +-----Contact
              CustTotal
              rsDetail
                  |
                  +----Customers.*
                       ExtendedPrice
              customerid
				

Hierarquia complexa:

Este exemplo ilustra uma hierarquia que contém um conjunto de linhas principais, conjuntos de dois subordinados linhas, um dos quais é parametrizado, e um detalhe de grupo.
   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
				

Principal agrupado relativas a subordinado agrupado:

   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
				
os lucros:
   rsCustomers
        |
        +-----customers.*
              rsOrdByMonth
                 |
                 +-----rsOrders
                            |
                            +---- Orders.*
                       customerid
                       OrderYear
                       OrderMonth
   region
				

Cláusula SHAPE formal gramática

  <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.
				

Programas de teste SHAPE VBA

O seguinte código de programa do VBA permite escrever nos seus próprios comandos SHAPE e mostrar a hierarquia de campo ou indicar a localização do erro de sintaxe.

aviso : USE O código fornecido neste artigo AT YOUR próprio riscos. A Microsoft fornece este código "tal como está" sem garantias de qualquer tipo, expressas ou implícita, incluindo sem limitação as garantias implícitas de comercialização e/ou adequação a um fim específico.
  1. O administrador de ODBC do painel de controlo adicione um DSN para o controlador ODBC do Microsoft Access 97 chamado OLE_DB_NWIND_JET apontando para a base de dados Adamastor (ou NWIND).
  2. Crie um novo projecto. Adicione duas caixas de texto (Texto1 e Texto2) e um botão de comando (Command1).
  3. Se ambas as caixas de texto suficientemente grandes para apresentar várias linhas de texto e definir as seguintes propriedades:
          Multiline: True                (Visual Basic only)
          Scrollbars: Vertical
          Font: Courier New 10 Point
    					
  4. No menu projecto , seleccione References e adicionar uma referência à Microsoft ActiveX Data Objects Library.
  5. Adicione o seguinte código:
       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. Execute o projecto. Escreva o comando SHAPE em Text1, clique no botão de comando e a hierarquia aparece em Text2.
Nota : O texto seguinte fornece um exemplo de utilizando o fornecedor de OLEDB do Microsoft Jet com o fornecedor SHAPE:
  cn.Provider = "MSDataShape"
  cn.Open "Data Provider=Microsoft.Jet.OLEDB.4.0"
				
Nota : se como nomes de campo ou tabela quando utilizar o controlador ODBC do Access 97 ou JOLT fornecedores, receberá a seguinte mensagem:
Muito poucos parâmetros. N esperado.
Outros fornecedores podem produzir uma mensagem diferente.

Referências

ADO 2.0 hierárquica especificação do cursor

Para obter informações adicionais sobre sintaxe SHAPE APPEND e a atravessar conjuntos de registos hierárquicos, consulte o seguinte artigo na base de dados de conhecimento da Microsoft:
185425  (http://support.microsoft.com/kb/185425/EN-US/ ) ADO hierárquica conjuntos de registos através de APPEND SHAPE através de C + + / VBA/Java

A informação contida neste artigo aplica-se a:
  • 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
Palavras-chave: 
kbmt kbdatabase kbhowto kbprovider KB189657 KbMtpt
Tradução automáticaTradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine translation ou MT), não tendo sido portanto revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática? erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 189657  (http://support.microsoft.com/kb/189657/en-us/ )
Retired KB ArticleExclusão de Responsabilidade para Conteúdo sem Suporte na KB
Este artigo foi escrito sobre produtos para os quais a Microsoft já não fornece suporte. Por conseguinte, este artigo é oferecido "tal como está" e deixará de ser actualizado.