Обработка пустых значений с помощью ADO.NET и AddWithValue()
Вопрос
У меня есть элемент управления, который при обратной передаче сохраняет результаты формы обратно в базу данных.Он заполняет значения, которые необходимо сохранить, путем итерации по строке запроса.Итак, для следующего оператора SQL (значительно упрощенного для обсуждения)...
UPDATE MyTable
SET MyVal1 = @val1,
MyVal2 = @val2
WHERE @id = @id
... он будет циклически перебирать ключи строки запроса следующим образом:
For Each Key As String In Request.QueryString.Keys
Command.Parameters.AddWithValue("@" & Key, Request.QueryString(Key))
Next
ОДНАКО, сейчас я столкнулся с ситуацией, когда при определенных обстоятельствах некоторые из этих переменных могут отсутствовать в строке запроса.Если я не передам val2 в строке запроса, я получу ошибку: System.Data.SqlClient.SqlException: Must declare the scalar value "@val2"
.
Попытка обнаружить пропущенное значение в операторе SQL...
IF @val2 IS NOT NULL
UPDATE MyTable
SET MyVal1 = @val1,
MyVal2 = @val2
WHERE @id = @id
...провалился.
Какой лучший способ атаковать это?Должен ли я анализировать блок SQL с помощью RegEx, сканируя имена переменных, отсутствующие в строке запроса?Или есть более элегантный способ подойти?
ОБНОВЛЯТЬ:Обнаружение нулевых значений в коде VB противоречит цели отделения кода от его контекста.Я бы предпочел не засорять свою функцию условиями для каждой мыслимой переменной, которая может быть передана или не передана.
Решение 3
Пытаясь найти более простое решение, я сдался и написал процедуру для анализа моего SQL-запроса на предмет имен переменных:
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
Это своего рода хак, но он позволяет мне держать мой код в блаженном неведении относительно контекста моего SQL-запроса.
Другие советы
Прежде всего, я бы посоветовал не добавлять все записи в строку запроса в качестве имен параметров. Я не уверен, что это небезопасно, но я бы не стал рисковать.
Проблема в том, что ты звонишь
Command.Parameters.AddWithValue("@val2", null)
Вместо этого вы должны позвонить:
If MyValue Is Nothing Then
Command.Parameters.AddWithValue("@val2", DBNull.Value)
Else
Command.Parameters.AddWithValue("@val2", MyValue)
End If
Обновлять:Решение, которое я дал, основано на предположении, что это хранимая процедура.Будет ли работать установка значения по умолчанию Null для параметров процедуры, хранящихся в SQL?
Если это динамический SQL, всегда передавайте правильное количество параметров, будь то нулевое значение или фактическое значение, или указывайте значения по умолчанию.
мне нравится использовать AddWithValue
метод.
Я всегда указываю параметры SQL по умолчанию для «необязательных» параметров.Таким образом, если он пуст, ADO.NET не будет включать этот параметр, а хранимая процедура будет использовать его значение по умолчанию.
Таким образом мне не приходится иметь дело с проверкой/передачей DBNull.Value.