文章編號: 189657 - 上次校閱: 2004年7月13日 - 版次: 1.4

如何使用 ADO SHAPE 指令

系統提示本文適用於您使用的作業系統之外的作業系統。與您不相關的文章內容已停用。

在此頁中

全部展開 | 全部摺疊

結論

本文將告訴您,ADO SHAPE 命令語法,製造階層式資料錄集,並說明如何周遊階層式資料錄集。同時也提供 VBA 程式碼範例。

其他相關資訊

當您需要存取父-子和摘要資料時,您可以使用階層式資料錄集除了一個 JOIN 和 GROUP BY 語法。

在許多產品中使用階層式資料錄集: Xbase 產品使用 SET 關聯] 指令,內部的群組層次的報表的 Access 用途 「 分段的虛擬資料表 」,等等。階層架構讓您能夠建置一或多個資料錄集,定義群組,並透過子資料錄集指定彙總計算。雖然您可以實作類似的功能,透過程式碼,這項功能將切換的大部分例行工作從開發人員到系統。

階層式資料錄集都可以透過 MSDataShape 提供者由用戶端資料指標引擎所實作。

階層式資料錄集不同從 SQL JOIN] 和 [GROUP BY 陳述式與一個 JOIN,父資料表欄位和子資料表的欄位會表示相同的資料錄集。使用階層式資料錄集資料錄集包含只有從父資料表的欄位。在另外資料錄集包含代表關聯的子資料您可以指派給第二個資料錄集變數並周遊的額外欄位。

當您執行的彙總函式使用 GROUP BY 與彙總運算子時,彙總值僅會出現在記錄集中。與階層式資料錄集彙總值會代表父資料錄集中,而詳細資料記錄是在子資料錄集。

您可以建立三種類型的圖形,和每一種類型都有它自己的優點和缺點。您需要選擇最符合您的應用程式和您將執行您的應用程式的環境需求的機制。SHAPE 類型如下所示:
  • 架構的關聯
  • 參數型
  • 架構的群組
因為它們產生否則可表示由 SQL JOIN 陳述式的階層架構前, 兩個都類似。它們與不同在於,所有父和子資料錄讀入任何處理前的本機快取會繼續以關聯為基礎的階層架構中。這種類型的階層有高的初始額外負荷,擷取該記錄時,但是初始擷取之後很低額外負荷。

最初,參數為基礎的階層架構只讀取父資料錄,並在視需要擷取子資料錄。雖然減少初始的額外負荷必須發出存取每個父記錄新的子查詢,而且,只要是開啟的資料錄集,必須維持為資料來源連線。

群組階層架構相當於產生彙總 SQL 陳述式加入至詳細資料的 SQL 陳述式或非正規化的資料上執行彙總函數。您不能更新摘要的資料行和計算的資料行,因為它們可能會衍生自一個以上的記錄。像關聯為基礎的階層必須事先讀取所有記錄。

階層式資料錄集是可供 SHAPE 子句所使用。簡化的語法提供第一次,然後與圖表範例。因為 SHAPE 語法可以取得相當複雜正式文法對於 [SHAPE 子句提供可讓您擴充範例的文章結尾處。您也可以使用本文結尾處的程式來測試您自己 SHAPE 陳述式。這些範例使用從北風貿易範例資料庫的資料表。

簡化的語法

   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]
				

附註:

  1. 如果您從不同的資料表中選取相同具名的欄位您可能需要別名它們以確保 SHAPE 剖析器能夠運作。
  2. SHAPE 附加 的函式,同樣地以一個 OUTER JOIN 的父資料錄被傳回,即使沒有子記錄存在。
  3. 彙總只可以在資料錄集的直接子系中的欄位上作業。若要操作中孫子,等等的欄位上,您必須產生中繼彙總。群組階層架構,以取得說明本文結尾處的彙總範例,請參閱。
  4. 如果您使用彙總函式 SHAPE 附加 語法,彙總的值將佔滿附加至父結果集也包含從父陳述式欄位的欄位。相較之下,[SHAPE COMPUTESHAPE BY 建立新的父層級的彙總,而非正規化-陳述式會變成子資料錄集。
  5. SHAPE 提供者要求您包含別名陳述非-正規化-式 COMPUTE 子句使用 SHAPE COMPUTE 時中。失敗如果要執行這項操作,產生一則訊息不支援該功能,即使它不會導致語法錯誤。

範例

簡單關聯階層:

   SHAPE  {select * from customers}
   APPEND ({select * from orders} AS rsOrders
           RELATE customerid TO customerid)
				
哪一個會產生:
   Customers.*
   rsOrders
        |
        +----Orders.*
				
前圖在父資料錄集包含了 [客戶] 資料表的所有欄位,而欄位,稱為 rsOrders rsOrders 提供子資料錄集的參照,且都包含 [訂單] 中的所有欄位的資料表。其他範例使用類似的表示法。

參數化階層架構:

   SHAPE  {select * from customers}
   APPEND ({select * from orders where customerid = ?} AS rsOrders
           RELATE customerid TO PARAMETER 0)
				
這會導致相同階層為簡單關聯階層。

複合關聯階層:

這個範例說明的客戶、 訂單和訂單詳細資料的三層階層架構:
   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)
				
哪一個會產生:
   Customers.*
   rsOrders
        |
        +----Orders.*
             rsDetails
                 |
                 +----[Order Details].*
				

多個關聯階層:

這個範例說明涉及父資料錄集和兩個的子資料錄集,其中參數化的階層:
   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
				
哪一個會產生:
   Customers.*
   rsOldOrders
        |
        +----Orders.*
   rsRecentOrders
        |
        +----Orders.*
				

彙總的階層:

   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
				
哪一個會產生:
   Orders.*
   rsDetails
       |
       +----orderid
            ExtendedPrice
   OrderTotal
				

群組階層架構:

   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
				
哪一個會產生:
   rsOrders
       |
       +----cust_id
            Orders.*
   cust_id
				

與彙總群組階層架構:

注意: 在此範例中的 內部 SHAPE 子句是相同陳述式與彙總的範例將階層架構中使用。
   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
				

多個群組:

   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
				
哪一個會產生:
   rsCustSummary
        |
        +-----Contact
              Region
              CustTotal
              rsDetail
                   |
                   +----Customers.*
                        ExtendedPrice
              customerid
   Region
				

總計總計:

   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
				
請注意缺少 BY 子句在外部的摘要。因為父資料列集包含單一記錄具有總計] 和 [子資料錄集的指標,這個屬性定義 [總計。
   GrandTotal
   rsCustSummary
        |
        +-----Contact
              CustTotal
              rsDetail
                  |
                  +----Customers.*
                       ExtendedPrice
              customerid
				

複雜的階層架構:

這個範例說明包含一個父資料列集的階層、 資料列兩個子集,其中參數化和群組詳細資料。
   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
				

分組相關群組的子系的父代:

   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
				
哪一個會產生:
   rsCustomers
        |
        +-----customers.*
              rsOrdByMonth
                 |
                 +-----rsOrders
                            |
                            +---- Orders.*
                       customerid
                       OrderYear
                       OrderMonth
   region
				

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.
				

VBA SHAPE 測試程式

下列的 VBA 程式碼可讓您鍵入您自己 SHAPE 命令中的,並顯示欄位階層或指示語法錯誤的位置。

警告: 在 CODE YOUR 自己風險本文中所提供的 USE。 Microsoft 提供 「 現狀 」 這個程式碼並不提供任何種類明示或默示包括但不是限於適售性以及適合某特定用途之默示擔保責任。
  1. 在 [控制台] 的 [ODBC 管理員新增稱為 OLE_DB_NWIND_JET 指向北風 (或 NWIND) 資料庫的 Microsoft Access 97 ODBC 驅動程式的資料來源名稱。
  2. 建立新的專案。加入兩個文字方塊 (文字 1 及 [文字 2]) 和指令按鈕 (Command1)。
  3. 使這兩個文字方塊大到足以顯示幾行文字,並設定下列屬性:
          Multiline: True                (Visual Basic only)
          Scrollbars: Vertical
          Font: Courier New 10 Point
    					
  4. 在 [專案] 功能表上選擇 引用項目,並新增 Microsoft ActiveX 資料物件的參考文件庫。
  5. 加入下列程式碼:
       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. 執行專案。SHAPE 命令輸入 [文字 1]、 按一下 [命令] 按鈕,並在階層架構出現在 [文字 2]。
附註: 下列的文字提供與 SHAPE 提供者使用 Microsoft Jet OLEDB 提供者的範例:
  cn.Provider = "MSDataShape"
  cn.Open "Data Provider=Microsoft.Jet.OLEDB.4.0"
				
注意: 若您拼錯欄位或資料表的名稱,使用 Access 97 ODBC 驅動程式或 JOLT 提供者時,您會收到下列訊息:
參數太少。預期的 n。
其他提供者可能會產生不同的訊息。

?考

ADO 2.0 的階層式資料指標規格

如需有關 SHAPE 附加 語法以及如何周遊階層式資料錄集的詳細資訊,請參閱 「 Microsoft 知識庫 」 中下列文:
185425? (http://support.microsoft.com/kb/185425/EN-US/ ) ADO 階層式記錄集透過 SHAPE 附加透過 C + + / VBA/Java

這篇文章中的資訊適用於:
  • 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
關鍵字:?
kbmt kbdatabase kbhowto kbprovider KB189657 KbMtzh
機器翻譯機器翻譯
重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。
按一下這裡查看此文章的英文版本:189657? (http://support.microsoft.com/kb/189657/en-us/ )
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。
Retired KB Article依現狀不再更新的知識庫內容免責聲明
本文旨在說明 Microsoft 不再提供支援的產品。因此,本文係依「現狀」提供,不會再更新。