SQL versus DAO ◦ ?

Oft stehen eine mengen- und eine satzorientierte Abfragesprache zur Wahl. Die folgende Aufgabe können Sie zum Beispiel mit DAO satzorientiert oder mit SQL mengenorientiert lösen.

### Spezifikation

Wer im Stammformular FrmAllgemeines den Aufgabentyp Mehrfachwahl wählt und dann die Schaltfläche Aufgabe bearbeiten drückt, gelangt in das Formular FrmMehrfachwahl. Darin können Sie einen Frage und vier Alternativen anfügen. Falls eine Mehrfachwahlaufgabe noch keine Einträge enthält, fügt die Ereignisprozedur Form_Open von FrmMehrfachwahl Skelette für die Frage und die vier Alternativen ein. Die Aufgabenstellung ist ähnlich wie jene in Navigation durch Recordsets. Hier wird allerdings die Datenherkunft des Formulars für die Erstellung statt für die Lösung einer Mehrfachwahlaufgabe initialisiert. Die Alternativenskelette sehen wie folgt aus:

Eine noch leere Alternative wird durch ihren Schlüssel - eine Zahl zwischen 1 und 4 - eingeleitet und enthält dann einen leeren Alternativentext, dessen Markierungskästchen am rechten Rand noch leer ist.

### Entwurfscode

Der folgende Entwurfscode skizziert die Ablauflogik:

>     Öffne FrmMehrfachwahl
>       Falls zum Fragenschlüssel der laufenden Aufgabe kein Fragentext existiert dann
>         Füge der Tabelle FRAGENTEXT eine Zeile mit den folgenden Attributwerten an:
>           Fragenschlüssel = Fragenschlüssel der laufenden Aufgabe
>           Fragentext = ""
>         Füge der Tabelle MEHRFACH_ALTERNATIVEN vier Zeilen mit den folgenden Attributwerten an:
>           Fragenschlüssel = Fragenschlüssel der laufenden Aufgabe
>           Alternativenschlüssel = 1 bzw. 2 bzw. 3 bzw. 4
>           Alternativentext = ""
>           Musterlösung = 0

### Programmcode

Der Entwurfscode lässt sich entweder mit DAO oder SQL implementieren. Beide Varianten prüfen zuerst, ob FRAGENTEXT bereits eine Zeile mit dem Fragenschlüssel der laufenden Aufgabe enthält. Wenn zum Beispiel für die Frage 1 das Ergebnis des Funktionsaufrufs DLookup("[Fragenschlüssel]", "FRAGENTEXT", "Fragenschlüssel = 1") Null ist (also noch keine Mehrfachwahlaufgabe mit dem Fragenschlüssel 1 existiert), dann kann entweder die DAO-Methode AddNew oder die SQL-Aktionsanweisung INSERT die fünf Skelettsätze anfügen.

Der DAO- bzw. SQL-typische Code ist fett markiert. Die DAO-Variante können Sie sich in Testverwaltung.mdb ansehen, indem Sie aus dem Formular FrmMehrfachwahl »Ansicht/Entwurfsansicht wählen, »Alt/Eingabetaste drücken und dann von der Ereignisprozedur »Beim Öffnen des Formulars zum Code gehen.

> #### a) DAO

>     '--- Alternativenskelette einfügen
>     Private Sub Form_Open(Cancel As Integer)
>       Dim LookupKriterium As String
>       Dim strFragenschlüssel As String
>       Dim vrtFragenschlüssel As Variant     'Variant, damit Ergebnis von DLookup mit IsNull prüfbar ist
>       Dim Alternativenschlüssel As Integer  'Laufvariable
>       Dim strAlternativenschlüssel As String

>       Dim dbs As Database
>       Dim rstMEHRFACHWAHL_ALTERNATIVEN As Recordset
>       Dim rstFRAGENTEXT As Recordset

>       'OpenArgs ist das beim Öffnen von FrmMehrfachwahl aus FrmAllgemeines übergebene Argument
>       strFragenschlüssel = Forms!FrmMehrfachwahl.OpenArgs
>       LookupKriterium = "[Fragenschlüssel]=" & strFragenschlüssel
>       '"FRAGENTEXT" ist der Tabellen- und [Fragenschlüssel] der Attributname
>       vrtFragenschlüssel = DLookup("[Fragenschlüssel]", "FRAGENTEXT", LookupKriterium)
>       '-- Skelettsätze nur anfügen, falls Aufgabe neu
>       If IsNull(vrtFragenschlüssel) = True Then
>         Set dbs = CurrentDb
>         '-- E i n  Fragentext-Skelett
>         Set rstFRAGENTEXT = dbs.OpenRecordset("FRAGENTEXT")
>         With rstFRAGENTEXT
>           .AddNew
>             !Fragenschlüssel = strFragenschlüssel
>             !Fragentext = ""
>           .Update
>           .Close
>         End With
>         Set rstFRAGENTEXT = Nothing
>         '-- V i e r  Alternativenskelette
>         Set rstMEHRFACHWAHL_ALTERNATIVEN = dbs.OpenRecordset("MEHRFACHWAHL_ALTERNATIVEN")
>         With rstMEHRFACHWAHL_ALTERNATIVEN
>           For Alternativenschlüssel = 1 To 4
>             strAlternativenschlüssel = CStr(Alternativenschlüssel) 'CStr(Zahl) ergibt Str-Wert von Zahl
>             .AddNew
>               !Fragenschlüssel = strFragenschlüssel
>               !Alternativenschlüssel = strAlternativenschlüssel
>               !Alternativentext = ""
>               !Musterlösung = 0
>             .Update 'Datenbank-Update
>           Next Alternativenschlüssel
>           .Close
>         End With
>         Set rstMEHRFACHWAHL_ALTERNATIVEN = Nothing
>         Set dbs = Nothing
>       End If
>       Requery 'Bildschirm-Update
>     End Sub

> #### b) SQL

>       Dim strSQL As String
>       '... (analog oben)

>       '--- Alternativenskelette
>       strSQL = "INSERT INTO FRAGENTEXT " & _
>         "(Fragenschlüssel, Fragentext) " & _
>         "VALUES ('" & strFragenschlüssel & "', '');"
>       dbs.Execute strSQL, dbFailOnError
>       For Alternativenschlüssel = 1 To 4
>         strAlternativenschlüssel = CStr(Alternativenschlüssel)
>         strSQL = "INSERT INTO MEHRFACHWAHL_ALTERNATIVEN " & _
>           "(Fragenschlüssel, Alternativenschlüssel, Alternativentext, Musterlösung) " & _
>           "VALUES ('" & strFragenschlüssel & "', '" & strAlternativenschlüssel & "', '', '0');"
>         dbs.Execute strSQL, dbFailOnError
>       Next Alternativenschlüssel

>       '...(analog zu oben)

> SQL-Anweisungen, die aus prozeduralem Code aufgerufen werden, nennt man eingebettet.

### Weitere Beispiele der satzorientierten Verarbeitung

Die folgenden Beispiele zeigen, dass sich die satzorientierte (prozedurale) Vorgehensweise manchmal besser eignet als die mengenorientierte (deklarative):

> Formatierung von Zuordnungslösungen
> Kumulative Notenhäufigken

Satzorientierte Verarbeitung unter DAO
INSERT
DAO-Methode AddNew