Visual Basic - Technik, FAQ, Tricks, Beispiele

Home / ASP / Service / Datenbank

Einfacher Datenbankzugriff mit DB.ASP

Einleitung

Der Datenbankzugriff mittels ADO ist sicher einer der wichtigsten Aspekte nicht nur in der ASP-Programmierung. Jedoch muss man (insbesondere im Vergleich zu den guten alten DAO-Methoden) einige Abstriche bzgl. der Übersichtlichkeit und Einfachheit machen.

Es ist z.B. nicht jedermanns Sache, extra für jeden DB-Zugriff via CreateObject ein Objekt anzulegen (und auch wieder aufzuräumen). Ausserdem sollten DB-Connections möglichst sparsam genutzt werden, d.h. immer nur kurz geöffnet und sofort wieder geschlossen werden, damit die Internet-Anwendung auch gut skalieren kann.

Routinen

Die unten definierten Routinen ermöglichen eine einfache und komfortable Nutzung von Datenbanken via ADO. Man beachte, dass für DBUpdate und DBDelete numerische Primärschlüssel benötigt werden:

Sub DBOpen(Connect)

Mit dieser Prozedur wird der ConnectString (Connect) für die Datenbank angegeben. Im Gegensatz zur Open-Methode von ADO.Connection wird die Datenbank jedoch noch nicht geöffnet.

Wird ein Pfad zu einer Access-Datenbank übergeben, so wird automatisch der entsprechende ODBC- bzw. OLEDB-ConnectString zusammengebaut (ggf. Konstante AccessConnect anpassen, s.u.).

Übrigens wird als Default-Datenbank Server.MapPath("data.mdb") verwendet.

Function DBInsert(Table, Key, Fields, Values)

Mit dieser Funktion wird ein Datensatz in die Tabelle Table eingefügt. Fields und Values sind entweder mit der Array-Funktion zusammengestellte Felder, oder einfache (skalare) Werte.

Die Funktion gibt übrigens den numerischen Primärschlüssel (Feldname wird in Key angegeben) zurück, so dass der Umgang mit automatisch generierten IDs keine Probleme mehr bereiten sollte.

Sub DBUpdate(Table, Key, KeyValue, Fields, Values)

Mit dieser Prozedur wird ein bestimmter Datensatz (identifiziert durch Key=KeyValue) in der Tabelle Table aktualisiert. Fields und Values sind genau wie bei DBInsert definiert.

Sub DBDelete(Table, Key, KeyValue)

Mit dieser Prozedur wird ein bestimmter Datensatz (identifiziert durch Key=KeyValue) aus der Tabelle Table gelöscht.

Function DBExecute(SQL)

Diese Funktion erlaubt die Ausführung von beliebigen SQL-Statements (falls die anderen Routinen mal nicht genügen sollten). Es wird die Anzahl der betroffenen Datensätze zurückgeliefert.

Function DBValue(SQL)

Mit dieser Funktion kann sehr schnell der Inhalt eines bestimmten (durch das SQL-Statement angegeben) Datenbank-Feldes gelesen werden. Wird kein entsprechender Datensatz gefunden, so wird Empty zurückgeliefert.

Enthält das SQL-Statement mehr als eine Spalte, so wird ein Dictionary-Objekt mit den Feldnamen und -Inhalten des selektierten Datensatzes zurückgegeben. Wird in diesem Fall kein entsprechender Datensatz gefunden, so wird Nothing zurückgeliefert.

Function DBSelect(SQL)

Reicht die DBValue-Funktion nicht aus (weil die Inhalte mehrerer Datensätze benötigt werden), so kann mit dieser Funktion ein vollwertiger ADO.RecordSet auf Basis des angegebenen SQL-Statements erstellt werden.

Beispiel

Das folgende Beispiel zeigt den Umgang mit DB.ASP: Zuerst muss natürlich die Include-Datei bekanntgemacht werden. Anschließend können die darin definierten Routinen benutzt werden:

<!--#include file="inc/db.asp"-->
<%
Response.Buffer = False
Dim NewID
PrintBold "Default-Connect:"
Response.Write DBConnect & "<br>"
PrintBold "Connect nach DBOpen:"
DBOpen Server.MapPath("firma.mdb")
Response.Write DBConnect & "<br>"
PrintBold "Initiale Daten:"
ShowDataset
PrintBold "DBInsert:"
NewID = DBInsert("tMitarbeiter", "ID", _
    Array("Name", "GebJahr", "Stufe"), _
    Array("Schmidt", 1982, 5))
ShowDataset
PrintBold "DBUpdate:"
DBUpdate "tMitarbeiter", "ID" , NewID, _
    "Name", "Schmitt"
ShowDataset
PrintBold "DBUpdate (mehrere Felder):"
DBUpdate "tMitarbeiter", "ID" , NewID, _
    Array("GebJahr", "Stufe"), _
    Array(1983, 4)
ShowDataset
PrintBold "DBValue:"
Response.Write DBValue("select count(*) from tMitarbeiter")
PrintBold "DBDelete:"
DBDelete "tMitarbeiter", "ID" , NewID
ShowDataset
'Alle Datensätze anzeigen:
Sub ShowDataset()
  Dim SQL, rs

  WaitForCache
  Response.Write "<i>Name/GebJahr, Stufe</i><br>"
  SQL = "select ID,Name,GebJahr,Stufe" _
      & " from tMitarbeiter" _
      & " order by Name"

  Set rs = DBSelect(SQL)
    Do Until rs.EOF
      If rs("ID") = NewID Then Response.Write "<b>"
      Response.Write rs("Name") & "/"
      Response.Write rs(2) & ", "
      Response.Write rs(3) & "<br>"
      If rs("ID") = NewID Then Response.Write "</b>"
      rs.MoveNext
    Loop
  rs.Close
  Set rs = Nothing
End Sub
'Wegen JetEngine-Cache etwas warten:
Sub WaitForCache()
  Dim t

  t = DateAdd("s", 1, Now)
  Do Until Now > t
  Loop
End Sub
'Neuen Testfall visualisieren:
Sub PrintBold(s)
  Response.Write "<hr><b>" & s & "</b><br>"
End Sub
%>

Das Ausführen des obigen Beispiels führt etwa zu folgender Ausgabe:

Default-Connect:
Driver={Microsoft Access Driver (*.mdb)};DBQ=D:\Inetpub\wwwroot\aspvb\data.mdb

Connect nach DBOpen:
Driver={Microsoft Access Driver (*.mdb)};DBQ=D:\Inetpub\wwwroot\aspvb\firma.mdb

Initiale Daten:
Name/GebJahr, Stufe
Meier/1970, 7
Müller/1980, 5
Schwider/1965, 8

DBInsert:
Name/GebJahr, Stufe
Meier/1970, 7
Müller/1980, 5
Schmidt/1982, 5
Schwider/1965, 8

DBUpdate:
Name/GebJahr, Stufe
Meier/1970, 7
Müller/1980, 5
Schmitt/1982, 5
Schwider/1965, 8

DBUpdate (mehrere Felder):
Name/GebJahr, Stufe
Meier/1970, 7
Müller/1980, 5
Schmitt/1983, 4
Schwider/1965, 8

DBValue:
4
DBDelete:
Name/GebJahr, Stufe
Meier/1970, 7
Müller/1980, 5
Schwider/1965, 8

Code / Quelltext

Die folgende Include-Datei enthält alles, um die üblichen Datenbank-Operationen komfortabel durchführen zu können. Am Besten wird diese Datei in ein Verzeichnis "inc" unter dem Namen "db.asp" abgespeichert.

Im Code wird zuerst via Metadata die ADO-Bibliothek bekanntgemacht, so dass alle ADO-spezifischen Konstanten (adOpenKeyset, adLockOptimistic, ...) zur Verfügung stehen. Die anschließenden Routinen sind übrigens alphabetisch sortiert:

<!--metadata type=typelib uuid="00000200-0000-0010-8000-00AA006D2EA4"-->
<%
'Beim Include ausführen:
Public DBConnect
DBOpen Server.MapPath("data.mdb")
'Datensatz löschen:
Sub DBDelete(Table, Key, KeyValue)
  Dim SQL

  SQL = "delete from " & Table _
      & " where " & Key & "=" & KeyValue
  DBExecute SQL
End Sub
'SQL-Statement ausführen:
Function DBExecute(SQL)
  Dim db

  Set db = Server.CreateObject("ADODB.Connection")

  db.Open DBConnect
    db.Execute SQL, DBExecute
  db.Close

  Set db = Nothing
End Function
'Datensatz einfügen:
Function DBInsert(Table, Key, Fields, Values)
  Dim SQL
  Dim rs
  Dim i

  'Leerstrings in Null konvertieren:
  If IsArray(Values) Then
    For i = LBound(Values) To UBound(Values)
      If Values(i) = "" Then Values(i) = Null
    Next 'i
  Else
    If Values = "" Then Values = Null
  End If

  '0 Datensätze holen...
  SQL = "select * from " & Table & " where 1=0"
  Set rs = Server.CreateObject("ADODB.RecordSet")

  rs.Open SQL, DBConnect, adOpenKeyset, adLockOptimistic
    rs.AddNew Fields, Values
    DBInsert = rs(Key)
  rs.Close

  Set rs = Nothing
End Function
'Datenbank öffnen:
Sub DBOpen(Connect)
  Const AccessConnect = _
      "Driver={Microsoft Access Driver (*.mdb)};DBQ="
    ' "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="

  If Mid(Connect, 2, 1) = ":" Or Left(Connect, 2) = "\\" Then
    'Access-Datenbank:
    DBConnect = AccessConnect & Connect
  Else
    'ODBC/OLE-Connectstring:
    DBConnect = Connect
  End If
End Sub
'Dataset öffnen:
Function DBSelect(SQL)
  Set DBSelect = Server.CreateObject("ADODB.Recordset")
  DBSelect.Open SQL, DBConnect
End Function
'Datensatz aktualisieren:
Sub DBUpdate(Table, Key, KeyValue, Fields, Values)
  Dim SQL
  Dim rs

  SQL = "select * from " & Table _
      & " where " & Key & "=" & KeyValue
  Set rs = Server.CreateObject("ADODB.RecordSet")

  rs.Open SQL, DBConnect, adOpenKeyset, adLockOptimistic
    If Not rs.EOF Then rs.Update Fields, Values
  rs.Close

  Set rs = Nothing
End Sub
'Datensatz holen:
Function DBValue(SQL)
  Dim rs
  Dim i

  Set rs = Server.CreateObject("ADODB.Recordset")
  rs.MaxRecords = 1

  rs.Open SQL, DBConnect
    If rs.Fields.Count = 1 Then

      'Einzelnen Wert zurückliefern:
      If Not rs.EOF Then DBValue = rs(0)

    Else

      'Wertemenge als Dictionary zurückliefern:
      If rs.EOF Then
        Set DBValue = Nothing
      Else
        Set DBValue = Server.CreateObject("Scripting.Dictionary")
        For i = 0 To rs.Fields.Count - 1
          DBValue.Add rs(i).Name, rs(i).Value
        Next 'i
      End If

    End If
  rs.Close

  Set rs = Nothing
End Function
%>

© Jost Schwider, 10.09.2001-10.09.2001 - http://vb-tec.de/aspdb.htm