Glengamoi (Forum) · AspHeute · .NET Heute (RSS-Suche) · AspxFiles (Wiki) · .NET Blogs
ASP German Homepage Homepage
 

Liste

.NET 2.0 (1)
.NET Allgemein (16)
.NET Fu (5)
ADO.NET (11)
Aprilscherz (3)
ASP Grundlagen (44)
ASP Tricks (83)
ASP.NET (44)
ASPIntranet.de (5)
C# (28)
Datenbank (44)
Dokumentation (4)
IIS 6.0 (1)
Komponenten (29)
Optimierung (10)
Server (21)
Sicherheit (34)
Tee Off (6)
VB.NET (6)
WAP (8)
Web Services (11)
XML (9)

RSS 2.0 - Die neuesten fünf Artikel auf AspHeute.com


 

Suchen





 

English Articles
Chinese Articles
Unsere Autoren
 
Link zu AspHeute
Impressum
Werben
Anfragen

Das Dictionary Objekt - Dein Feind und Helfer

Geschrieben von: Christoph Wille
Kategorie: ASP Tricks

Eine Komponente, die ein Schattendasein fristet (beziehungsweise gefristet hat) ist das Dictionary Objekt. Dabei kann es sehr nützlich sein. Wer PERL kennt, kennt die assoziativen Arrays - genau das ist ein Dictionary. Für die, die PERL nicht kennen und sich unter einem assoziativen Array nichts vorstellen können, hier die Kurzfassung: ein Schlüsselwert wird verwendet um einen zugewiesenen Wert aufzufinden (zB: eine nette Assoziation ist Flensburg und Polizei).

Also gleich mal zu einem Beispiel zum leichteren Verständnis:

Set myDictionary = CreateObject("Scripting.Dictionary")
myDictionary.Add "Flensburg", "Polizei"
myDictionary.Add "Kuba", "Zigarren"
Damit erstelle ich die Assoziation, die ich dann verwenden kann, um das Teil wieder aufzusuchen:
Response.Write myDictionary.Item("Flensburg")
Das Resultat ist wie nicht anders zu erwarten - "Polizei". Vernünftigere Anwendungen wären Benutzername zu Paßwort Zuweisungen oder das Auslesen von Daten aus Tabellen (Primärschlüssel zugewiesen auf zB Nachname).

Damit sind wir auch schon beim Thema, das Verwenden von Dictionaries zusammen mit Recordsets. Da gibt es nämlich eine unheilige Allianz, die ich anhand des folgenden Beispiels erklären werde (ich verwende die pubs Datenbank eines SQL 7 Servers names TOPGUN):

<% 
Dim oConn, oRS, dicAuthors
Set oConn = CreateObject("ADODB.Connection")
oConn.ConnectionString = "provider=sqloledb.1;user id=sa;" & _
		"password=;initial catalog=pubs;data source=TOPGUN"
oConn.Open

Set oRS = CreateObject("ADODB.Recordset")
oRS.ActiveConnection = oConn
oRS.Open "SELECT au_id, au_lname FROM authors"

Set dicAuthors = CreateObject("Scripting.Dictionary")
while not oRS.EOF
	dicAuthors.Add oRS(0), oRS(1)
	oRS.MoveNext
wend

oRS.Close
oConn.Close

Dim myKeys, myValues, i
myKeys = dicAuthors.Keys
myValues = dicAuthors.Items
For i = 0 To (dicAuthors.Count -1)
	Response.Write myKeys(i) & " " & myValues(i)
Next
%>
Eigentlich nichts besonders - außer daß ich statt über ODBC direkt über den OLE-DB Treiber auf den SQL Server zugreife (bringt Geschwindigkeit, weil der ODBC Layer ausgeschaltet wird).

Der eigentliche Haken an der Geschichte ist die while-Schleife:

while not oRS.EOF
	dicAuthors.Add oRS(0), oRS(1)
	oRS.MoveNext
wend
Wenn ich das so laufen lasse, dann bekomme ich folgende Fehlermeldung:
Microsoft VBScript runtime error '800a01c9' 
This key is already associated with an element of this collection 
/ASPGERMAN/dictionary2recordset.asp, line 21 
Analyse: Der Fehler tritt bei der zweiten Datensatzzeile auf; der Primärschlüssel au_id ist aber eindeutig - was also ist da passiert? Der Grund liegt im Dictionary selbst - ich kann Objekte zuweisen, und zwar auf den Schlüssel und den Wert (da wird die Adresse und nicht der Wert des Objekts gespeichert). Da ADO aber für oRS.Fields(0) immer das gleiche Field Objekt liefert, ist dessen Adresse im Speicher immer die gleiche - und somit ist beim 2ten Durchlauf der Fehler vorprogrammiert. Der Fehler läßt sich aber leicht beheben:
	dicAuthors.Add CStr(oRS(0)), oRS(1)

Damit weise ich den Wert des Objekts (ein String) statt der Adresse des Objekts zu. Wenn ich das Skript jetzt laufen lasse, wird der Fehler allerdings noch um einiges lustiger, und zwar tritt er in der 2ten Zeile des folgenden Codes auf:

For i = 0 To (dicAuthors.Count -1)
	Response.Write myKeys(i) & " " & myValues(i)
Next
Und die Fehlermeldung schulde ich Euch noch:
error '80020009' 
Exception occurred. 
/ASPGERMAN/dictionary2recordset.asp, line 32 
Ich hoffe, einige haben das mit der Objektadresse aufmerksam gelesen - ich habe gesagt, Schlüssel und Wert können ein Objekt aufnehmen, und genau das mache ich immer noch - der Wert ist oRS.Fields(1), mit dem Haken, daß ich das Recordset schon geschlossen habe. Damit ist das Field Objekt schon gelöscht, und wenn ich zugreife, bekomme ich die Zugriffsverletzung. Auch dieser Fehler läßt sich mit der bekannten Methode beseitigen:
	dicAuthors.Add CStr(oRS(0)), CStr(oRS(1))

Was wäre passiert, wenn das Recordset noch nicht geschlossen gewesen wäre? Ich hätte einen einzigen Wert bekommen, und zwar den, der in der letzten Zeile gestanden ist. Selbstversuch!

Die Moral von der Geschichte? Dictionaries sind ein mächtiges Werkzeug - sie nehmen alles auf (inklusive Objekten), wie man dann an die Daten wieder herankommt sollte man sich aber bereits vorher überlegt haben. Die Fehler können gemein schwer zu finden sein!

Verwandte Artikel

Allgemeine MailParser-Klasse mit ASPMail
Collections einmal anders: Stacks und Queues
Die LookUpTable Komponente
Große Datenmengen in Formularfeldern erfolgreich auslesen
Klassenauflistungen mit dem Dictionary-Objekt
Meta Tags von fremden Seiten parsen

Wenn Sie jetzt Fragen haben...

Wenn Sie Fragen rund um die in diesem Artikel vorgestellte Technologie haben, dann schauen Sie einfach bei uns in den Community Foren der deutschen .NET Community vorbei. Die Teilnehmer helfen Ihnen gerne, wenn Sie sich zur im Artikel vorgestellten Technologie weiterbilden möchten.

Haben Sie Fragen die sich direkt auf den Inhalt des Artikels beziehen, dann schreiben Sie dem Autor! Unsere Autoren freuen sich über Feedback zu ihren Artikeln. Ein einfacher Klick auf die Autor kontaktieren Schaltfläche (weiter unten) und schon haben Sie ein für diesen Artikel personalisiertes Anfrageformular.

 

Und zu guter Letzt möchten wir Sie bitten, den Artikel zu bewerten. Damit helfen Sie uns, die Qualität der Artikel zu verbessern - und anderen Lesern bei der Auswahl der Artikel, die sie lesen sollten.

Bewerten Sie diesen Artikel
 Sehr gut   Nicht genügend  
   1  2  3  4  5  
 

  
   Für Ausdruck optimierte Seite

©2000-2006 AspHeute.com
Alle Rechte vorbehalten. Der Inhalt dieser Seiten ist urheberrechtlich geschützt.
Eine Übernahme von Texten (auch nur auszugsweise) oder Graphiken bedarf unserer schriftlichen Zustimmung.