Handhabung leerer Werte mit ADO.NET und AddWithValue ()
Frage
Ich habe eine Kontrolle, die auf Postbacks, Formularergebnisse zurück in die Datenbank gespeichert werden. Es füllt die Werte durch Iterieren durch die Abfragezeichenfolgeflag gespeichert werden. Also, für die folgende SQL-Anweisung (in beträchtlichem Ausmaß aus Gründen der Diskussion vereinfacht) ...
UPDATE MyTable
SET MyVal1 = @val1,
MyVal2 = @val2
WHERE @id = @id
... es würde Zyklus durch die Abfragezeichenfolgeflag Tasten so:
For Each Key As String In Request.QueryString.Keys
Command.Parameters.AddWithValue("@" & Key, Request.QueryString(Key))
Next
Aber ich bin jetzt in einer Situation ausgeführt wird, wo unter bestimmten Umständen nicht in der Abfragezeichenfolgeflag einige dieser Variablen vorhanden sein. Wenn ich entlang val2 im Abfragezeichenfolgeflag nicht passieren, erhalte ich eine Fehlermeldung: System.Data.SqlClient.SqlException: Must declare the scalar value "@val2"
Versuche, den fehlenden Wert in der SQL-Anweisung zu erkennen ...
IF @val2 IS NOT NULL
UPDATE MyTable
SET MyVal1 = @val1,
MyVal2 = @val2
WHERE @id = @id
... ausgefallen ist.
Was ist der beste Weg, dies zu attackieren? Muss ich den SQL-Block mit RegEx, Scannen für Variablennamen nicht in der Abfragezeichenfolgeflag analysieren? Oder ist es eine elegantere Weise zu nähern?
UPDATE: Nullwerte in der VB Code-Behind-Erkennung Niederlagen der Zweck den Code aus seinem Kontext zu entkoppeln. Ich möchte lieber nicht Wurf meine Funktion mit Bedingungen für jede denkbare Variable, die weitergegeben werden könnten oder nicht bestanden.
Lösung 3
Nach dem Kampf eine einfachere Lösung zu finden, gab ich auf und schrieb eine Routine, meine SQL-Abfrage für Variablennamen zu analysieren:
Dim FieldRegEx As New Regex("@([A-Z_]+)", RegexOptions.IgnoreCase)
Dim Fields As Match = FieldRegEx.Match(Query)
Dim Processed As New ArrayList
While Fields.Success
Dim Key As String = Fields.Groups(1).Value
Dim Val As Object = Request.QueryString(Key)
If Val = "" Then Val = DBNull.Value
If Not Processed.Contains(Key) Then
Command.Parameters.AddWithValue("@" & Key, Val)
Processed.Add(Key)
End If
Fields = Fields.NextMatch()
End While
Es ist ein bisschen wie ein Hack, aber es erlaubt mir, meinen Code zu halten, völlig ahnungslos von Rahmen meiner SQL-Abfrage.
Andere Tipps
Zunächst einmal würde ich gegen vorschlagen alle Einträge auf der Abfragezeichenfolgeflag als Parameternamen hinzufügen, ich bin nicht sicher, dass dies nicht sicher ist, aber ich würde diese Chance nicht nehmen.
Das Problem wird Sie anrufen
Command.Parameters.AddWithValue("@val2", null)
Statt dessen sollten Sie anrufen:
If MyValue Is Nothing Then
Command.Parameters.AddWithValue("@val2", DBNull.Value)
Else
Command.Parameters.AddWithValue("@val2", MyValue)
End If
Update: Die Lösung Ich habe auf der Annahme, dass es sich um eine gespeicherte Prozedur ist. Wird ein Standardwert von Null auf die gespeicherte SQL-Prozedur Parameter geben arbeiten?
Wenn es dynamische SQL ist, immer die richtige Anzahl von params übergeben, ob es null ist oder der tatsächliche Wert oder Standardwert angeben.
Ich mag die AddWithValue
Methode.
angegebene Standard-SQL-Parameter für die „optional“ Parameter immer. Auf diese Weise, wenn es leer ist, ADO.NET wird der Parameter nicht enthalten, und die gespeicherte Prozedur verwenden, es ist Standardwert.
Ich muß in DBNull.Value nicht mit der Überprüfung umgehen / vorbei auf diese Weise.