Geschrieben von: Christoph Wille
Kategorie: Datenbank
This printed page brought to you by AlphaSierraPapa
Heute werden wir uns ein nützliches Tool für ASP in ASP selbst basteln - eine Page, die uns anhand eines Connection Strings und dem Namen einer Stored Procedure den notwendigen ADO/ASP VBScript Code zum Aufruf automatisch generiert - den man dann nur noch kopieren, und in die eigene Seite einbauen muß. Natürlich ist der generierte Code so schnell als möglich.
Einige werden bei dieser Funktionsbeschreibung an Features von Visual InterDev oder diversen Add-Ons für ebenso diverse Editoren denken. Wozu aber Geld ausgeben, wenn man es selbst programmieren kann?
Unsere Aufgabe besteht darin, aus den Inputs Connection String und Name der Stored Procedure den für den Aufruf notwendigen Code zu erstellen. Für den Aufruf einer Stored Procedure sind besonders die Parameter wichtig, die Pseudocode-mäßig wie folgt erzeugt werden:
Set adoParam = cmd.CreateParameter(Name, Datatype, Direction, Size, Value) cmd.Parameters.Append adoParam
Wie kommt man also an die Liste der Parameter? Das erledigt man mit der Refresh Methode:
Set cmd = Server.CreateObject("ADODB.Command") cmd.ActiveConnection = #Connection String# cmd.CommandText = #Name der Stored Procedure# cmd.CommandType = 4 ' adCmdStoredProc cmd.Parameters.Refresh
Grundsätzlich erhält man mit Refresh immer eine gefüllte Parameters Collection. Der Nachteil ist, daß dies Zeit und Netzwerktraffic "kostet" - ADO frägt den SQL Server um die notwendigen Informationen, und dies ist leider aufwendig und mit Roundtrips verbunden - und daher soll man ja auch die Parameter selbst generieren (mit dem Zweizeiler von weiter oben).
Da wir aber nicht auf Runtime Performance achten müssen, haben wir mit Refresh für unseren Zweck eigentlich schon gewonnen - und man könnte den ADO Code generieren (wie, das folgt sogleich). Aber, der Schönheitsfehler wäre, daß man die Konstantenwerte anstatt der symbolischen Konstantennamen generieren würde - wie im obigen Beispiel für adCmdStoredProc (der symbolische Name) und dem Konstantenwert 4 gezeigt. Diese sogenannten "magic values" erschweren das Lesen des Sourcecodes enorm.
Um das zu vermeiden, habe ich in den Code zur Generierung des ADO Codes zwei Hilfsfunktionen eingebaut:
Function GenerateADOStatement(ByVal strConnStr, ByVal strSP) Dim cmd, param, strParamAdd, strADOStatement Set cmd = Server.CreateObject("ADODB.Command") cmd.ActiveConnection = strConnStr cmd.CommandText = strSP cmd.CommandType = 4 cmd.Parameters.Refresh strADOStatement = "Set cmd = Server.CreateObject(""ADODB.Command"")" & vbCrLf strADOStatement = strADOStatement & "cmd.ActiveConnection = """ & strConnStr & """" & vbCrlf strADOStatement = strADOStatement & "cmd.CommandText = """ & strSP & """" & vbCrlf strADOStatement = strADOStatement & "cmd.CommandType = 4" & vbCrlf & vbCrlf For Each param In cmd.Parameters strParamAdd = "Set adoParam = cmd.CreateParameter(""" strParamAdd = strParamAdd & param.Name & """, " strParamAdd = strParamAdd & GetDataType(param.Type) & ", " strParamAdd = strParamAdd & GetDirection(param.Direction) & ", " strParamAdd = strParamAdd & param.Size & ", #enter value here#)" & vbCrlf strParamAdd = strParamAdd & "cmd.Parameters.Append adoParam" & vbCrlf strADOStatement = strADOStatement & strParamAdd Next Set cmd = Nothing strADOStatement = strADOStatement & vbCrlf & "' !! remove return value param !! " & vbCrlf strADOStatement = strADOStatement & "Set rs = cmd.Execute" GenerateADOStatement = strADOStatement End Function
Die fraglichen Funktionen sind GetDataType und GetDirection. Diesen übergebe ich den Konstantenwert, und bekomme als String den Namen der Konstanten zurück. Hier der Code für GetDirection, da GetDataType aufgrund der vielen möglichen Werte enorm lang ist:
Function GetDirection(ByVal nDirection) Dim strDirection Select Case nDirection Case 1 strDirection = "adParamInput" Case 3 strDirection = "adParamInputOutput" Case 2 strDirection = "adParamOutput" Case 4 strDirection = "adParamReturnValue" Case 0 strDirection = "adParamUnknown" Case Else strDirection = CStr(nDirection) End Select GetDirection = strDirection End Function
Der Sinn und Zweck des Case Else ist der, falls Microsoft neue Konstantennamen einfallen, das Skript für diese dann einfach den unbekannten Zahlenwert als String zurückliefert. Ich habe zwar dann einen "magic value" eingebaut, aber zumindest ist der Aufruf dennoch korrekt.
Natürlich habe ich rund um diese Funktionen ein harmloses, aber funktionelles Formular gebastelt. Nach einem Aufruf sieht das dann wie nachfolgender Screenshot aus:
Einfach den Namen der Stored Procedure und den Connection String eingeben, ADO Statements genieren klicken, und schon erhält man automatisch den gewünschten ADO Code.
Damit der generierte Code einfach allen Zwecken gerecht werden kann, muß man je nach Anwendungsfall etwas ändern. Generell muß man die #enter value here# Statements gegen die allfälligen Inputwerte an die Stored Procedure austauschen.
Und dann teilen sich die Wege der Anwendung - liefert die Stored Procedure als Rückgabewert ein Recordset oder einen Return Value? Hier die "Kochrezepte" für die einzelnen Fälle:
Für den Beispielfall der CustOrderHist Stored Procedure der Northwind Datenbank sehen die Änderungen dann wie folgt aus:
<!--METADATA NAME="Microsoft ActiveX Data Objects 2.5 Library" TYPE="TypeLib" UUID="{00000205-0000-0010-8000-00AA006D2EA4}" --> <% Set cmd = Server.CreateObject("ADODB.Command") cmd.ActiveConnection = "Provider=SQLOLEDB;Data Source=strangelove;..." cmd.CommandText = "CustOrderHist" cmd.CommandType = 4 ' Der Return Parameter ist gelöscht - wir erhalten ein Recordset! Set adoParam = cmd.CreateParameter("@CustomerID", adVarWChar, adParamInput, 5, "ALFKI") cmd.Parameters.Append adoParam Set rs = cmd.Execute ' Unser Code beginnt hier While Not rs.EOF Response.Write rs(0) & "<br>" rs.MoveNext Wend %>
Die ADO Konstanten kann man entweder über adovbs.inc oder über ein METADATA Statement einbinden. Ich persönlich bevorzuge letzteres, da damit immer die aktuellste ADO Version geladen wird.
Mit ein wenig Aufwand kann man sich ADO Code für Stored Procedures automatisch generieren lassen. Es ist jeder eingeladen, den heute vorgestellten Code an seine Bedürfnisse anzupassen.
This printed page brought to you by AlphaSierraPapa
Klicken Sie hier, um den Download zu starten.
http://www.aspheute.com/code/20010308.zip
ADO Component Checker Tool
http:/www.aspheute.com/artikel/20000329.htm
ADO und MDAC Versionen
http:/www.aspheute.com/artikel/20000327.htm
Auto-Generierung von performantem Abfragecode
http:/www.aspheute.com/artikel/20010329.htm
Code Generator für die AddNew Methode
http:/www.aspheute.com/artikel/20010327.htm
Gegengifte für SQL Injection
http:/www.aspheute.com/artikel/20011031.htm
Highspeed-Abfragen einer SQL Server Datenbank
http:/www.aspheute.com/artikel/20001013.htm
Records zählen mit Stored Procedures
http:/www.aspheute.com/artikel/20010326.htm
Stored Procedures einfach erstellt
http:/www.aspheute.com/artikel/20020903.htm
©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.