Tipp 4.14 - Hierarchische Beziehungen

Wie kann ich eine einfache hierarchische Beziehung mit SQL im Direktfenster darstellen?

Hierarchische Datensätze können sie leider nur mit ADO in Verbindung mit dem MSDataShape-Provider erstellen. Hierbei werden 1:1 bzw. 1:n Beziehungen zwischen Tabellen oder Abfragen in einem Recordset abgebildet. Dieses Recordset hat als Felder weitere Recordsets, die wiederum auch Recordset-Felder beinhalten können.

ExpertentippIhre Problemstellung: Sie möchten gerne eine Produktübersicht unterteilt nach Kategoriename und Artikelname im Direktfenster gestalten. Als Basis für unser kleines Beispiel greifen wir auf die Kategorien-Tabelle und auf die Artikel-Tabelle der Nordwind-Datenbank zurück.

Öffnen Sie ein neues Modul und binden Sie die Microsoft ActiveX Data Objects 2.X Library über ExtrasVerweise ein. Kopieren Sie nachstehenden Code in das Modul und führen Sie die Prozedur ShapeADO im Direktfenster aus:

Beispiel:

Public Sub ShapeADO()
 
  ' benötigte Variablen
  Dim sSql As String
  Dim sApp As String
  Dim sUti As String
 
  Dim cnn As ADODB.Connection
  Dim rst As ADODB.Recordset
 
  On Error GoTo ShapeADO_Err
 
  ' die SQL-Anweisung
  sSql = "SHAPE {SELECT tbl.[Kategorie-Nr] AS KatNr, tbl.Kategoriename FROM Kategorien AS tbl ORDER BY tbl.Kategoriename} AS Kat " & _
         "APPEND ( {SELECT sub.[Kategorie-Nr] AS KatNr, sub.Artikelname FROM Artikel AS sub ORDER BY sub.Artikelname} AS Produkt " & _
         "RELATE KatNr to KatNr) as Produktuebersicht"
 
  ' Ermitteln des Access-Verzeichnisses und
  ' Angabe der Nordwind-Datenbank
  sApp = SysCmd(acSysCmdAccessDir) & "\SAMPLES\Nordwind.mdb"
 
  Set cnn = New ADODB.Connection
 
  ' Connection öffnen
  With cnn
    .CursorLocation = adUseClient
    .Provider = "MSDataShape"
    .Properties("Data Provider") = "Microsoft.Jet.OLEDB.4.0"
    .Properties("Data Source") = sApp
    .Open
  End With
 
  Set rst = New ADODB.Recordset
 
  ' Recordset öffnen
  With rst
    .ActiveConnection = cnn
    .CursorLocation = adUseClient
    .CursorType = adOpenKeyset
    .LockType = adLockOptimistic
    .Source = sSql
    .Open
 
    If Not .BOF And Not .EOF Then
      ' Schleife über Hauptkategorie
      Do While Not .EOF
        ' Ausgabe des Kategorienamens
        Debug.Print "Kategorie: " & .Fields("Kategoriename").Value
        Debug.Print String(30, "=")
        ' Schleife über Produkte
        With .Fields("Produktuebersicht").Value
          Do While Not .EOF
            ' Ausgabe des Artikelnamens
            Debug.Print String(5, " "); .Fields("Artikelname").Value
            ' nächster Artikel
            .MoveNext
          Loop
        End With
        ' nächste Kategorie
        .MoveNext
        Debug.Print
      Loop
    End If
  End With
 
ShapeADO_Exit:
  On Error GoTo 0
  ' Speicher freigeben
  If Not rst Is Nothing Then rst.Close: Set rst = Nothing
  If Not cnn Is Nothing Then cnn.Close: Set cnn = Nothing
  Exit Sub
 
ShapeADO_Err:
  MsgBox "Fehler " & Err.Number & ": " & _
         Err.Description, vbCritical, _
         "modAdo.ShapeADO"
  Resume ShapeADO_Exit
 
End Sub
Erklärung der Codezeilen:

Der Provider MSDataShape schiebt sich wie eine zusätzliche Schicht zwischen Ihren Datenbanktreiber und den ADO-Objekten. Mit SHAPE – APPEND – RELATE führen Sie neue SQL-Befehle ein, die Ihnen grundsätzlich nur durch den MSDataShape-Provider zur Verfügung stehen.

Das Grundgerüst der Anweisung ist wie folgt aufgebaut:

SHAPE
  {Haupttabelle} AS <Alias>
APPEND
  (  {Detailtabelle} AS <Alias>
RELATE
  <Primärkey> TO <Detailkey> ) as <Alias>

Sie wählen mit der ersten SELECT-Anweisung die Felder der Haupttabelle aus, für die Sie Detaildatensätze anzeigen wollen. Anschließend werden die Felder mit der nächsten SELECT-Anweisung aus der Detailtabelle ausgewählt. Die Verbindung zwischen beiden Tabellen stellt die RELATE-Anweisung her. Hier wird der Primärschlüssel der Haupttabelle mit dem Fremdschlüssel der Detailtabelle verknüpft. Die Hierarchie wird anhand des Recordsets automatisch erkannt. Eigentlich ganz logisch, oder ;o)?

Die Ausgabe im Direktfenster
Kategorie: Fleischprodukte
------------------------------
     Alice Mutton
     Mishi Kobe Niku
     Pâté chinois
     Perth Pasties
     Thüringer Rostbratwurst
     Tourtière