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

Der ADO Command Code Generator

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?

Unser Codegenerator

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.

Der generierte 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.

Schlußbemerkung

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

Download des Codes

Klicken Sie hier, um den Download zu starten.
http://www.aspheute.com/code/20010308.zip

Verwandte Artikel

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.