ASP.NET Programmierung   ·   Microsoft MVP ASP/ASP.NET   ·   Peter Bucher   ·   Jürgen Gutsch   ·   Karsten Samaschke   ·   Microsoft ASP.NET
Willkommen bei ASP.NET Zone. Anmelden | Registrieren | Hilfe

OleDb: Parameter für OleDbCommand müssen zwingend in Reihenfolge sein?

Bekanntlicherweise ist es bei OleDbCommand Objekten, die bspw. auf eine Access Datenbank zugreifen, zwingend erforderlich, die verwendeten Parameter in der richtigen Reihenfolge anzugeben, da benannte Parameter hier nicht möglich sind.

Dim MySqlStatement     As String = "SELECT * FROM <Tabelle> WHERE <Spalte1> = ? AND <Spalte2> = ?"
Dim MyConnectionString As String = "PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=<PfadZurDatenbank>.mdb" )
Dim MyConnection       As New OleDbConnection( MyConnectionString )
    MyConnection.Open()
 
Dim MyCommand          As New OleDbCommand( MySqlStatement, MyConnection )
    MyCommand.Parameters.AddWithValue( "?", "Wert 1" )
    MyCommand.Parameters.AddWithValue( "?", "Wert 2" )
 
    ...
 
    MyCommand.Dispose()
 
    MyConnection.Close()
    MyConnection.Dispose()

Im Beispiel werden zwei Parameter verwendet. Über AddWithValue werden die Werte für die beiden Parameter zugeordnet. Man erwartet (und so ist es auch dokumentiert), dass "Wert 1" bei "<Spalte1>" und "Wert 2" bei "<Spalte2>" zugeordnet wird. Ist auch so. Aber, uns das ist das böse an der Sache, nicht bei SubSelects, wie bspw. einer IN Klausel.

Sähe das SQL Statement bspw. so aus ...

SELECT * FROM <Tabelle> WHERE <Spalte1> = ? AND <Spalte2> IN ( SELECT <SpalteX> FROM <AndereTabelle> WHERE <SpalteY> = ? )

... sollte man erwarten, dass "Wert 1" bei "<Spalte1>" und "Wert 2" bei <SpalteY>" - also im SubSelect - zugeordnet wird. Ist aber nicht so. In dem Fall muss man die Statements von innen nach außen auflösen, fürs Beispiel also die Befehle zum Hinzufügen der Parameter lediglich in der Reihenfolge vertauschen, also bspw. so:

    MyCommand.Parameters.AddWithValue( "?", "Wert 2" )
    MyCommand.Parameters.AddWithValue( "?", "Wert 1" )

Bei komplexeren bzw. tiefer verschachtelten SQL Statements kann das aber zum einen ziemlich eklig werden und zum anderen in Try&Error ausarten, was einer sicheren Arbeitsweise nicht wirklich zugänglich ist.

Die Ursache dürfte hier aber nicht bei .NET zu suchen sein. Gibt man nämlich eine parametrisierte Abfrage in Access ein und lässt diese ausführen, wird bei einem SubSelect ebenfalls der Parameter im inneren Statement zuerst vom Benutzer abgefragt. Von daher dürfte das ein "normales" Verhalten sein, welches aber doch sehr zur Verwirrung beiträgt, wenn man überall nur liest "die Reihenfolge der Parameter muss zwingend eingehalten werden".

Man könnte jetzt sagen: "Verwende halt ein DBMS, das benannte Parameter unterstützt" aber a) geht das auch nicht immer und b) arbeiten halt nunmal viele Leute immer noch mit OleDb und Access, ... Ergo: Bitte dokumentieren (Für den Fall, dass es dokumentiert ist, wäre ich für einen Link dankbar, ich hab bei einer - zugegebenermaßen sehr kurzen - Suche nichts dazu gefunden)

Als Anhang ein kleines Testprojekt, dass das Problem veranschaulicht (natürlich ist das nichts, was man so produktiv verwenden würde, es soll ja auch nur das Problem veranschaulichen und auf die Schnelle ist mir nichts besseres eingefallen :).

Edit: Ich habe die an dieser Stelle falsche bzw. nicht ausreichende MSDN Dokumentation mal bei Connect gemeldet. Wenn sich jemand dazu berufen fühlt, kann der- oder diejenige gerne das Problem dort bestätigen und/oder dafür abstimmen, dass es wichtig ist. Je mehr dies tun, desto größer ist die Chance, dass die Doku an den betreffenden Stellen erweitert wird.

https://connect.microsoft.com/VisualStudio/feedback/details/553888/doc-order-of-oledbparameter-objects-must-directly-correspond-to-the-position-is-wrong-with-subselects
Veröffentlicht Freitag, 23. April 2010 23:55 von Stefan Falz
Attachment(s): OleDbParameter.zip

Kommentare

Anonyme Kommentare sind nicht zugelassen