Обработка пустых значений с помощью ADO.NET и AddWithValue () - PullRequest
3 голосов
/ 15 сентября 2008

У меня есть элемент управления, который при обратной передаче сохраняет результаты формы обратно в базу данных. Он заполняет значения для сохранения путем итерации по строке запроса. Итак, для следующего оператора 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 отрицает цель отделения кода от его контекста. Я бы предпочел не засорять мою функцию условиями для каждой мыслимой переменной, которая может быть передана или не передана.

Ответы [ 4 ]

9 голосов
/ 15 сентября 2008

Прежде всего, я бы рекомендовал не добавлять все записи в строку запроса в качестве имен параметров, я не уверен, что это небезопасно, но я бы не воспользовался этим шансом.

Проблема в том, что вы звоните

Command.Parameters.AddWithValue("@val2", null)

Вместо этого вы должны звонить:

If MyValue Is Nothing Then
    Command.Parameters.AddWithValue("@val2", DBNull.Value)
Else
    Command.Parameters.AddWithValue("@val2", MyValue)
End If
0 голосов
/ 16 сентября 2008

Пытаясь найти более простое решение, я отказался и написал процедуру для анализа моего 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.

0 голосов
/ 15 сентября 2008

Мне нравится использовать метод AddWithValue.

Я всегда задаю параметры SQL по умолчанию для «необязательных» параметров. Таким образом, если он пуст, ADO.NET не будет включать этот параметр, а хранимая процедура будет использовать его значение по умолчанию.

Мне не нужно проверять / передавать в DBNull.Value таким образом.

0 голосов
/ 15 сентября 2008

Обновление: решение, которое я дал, основано на предположении, что это хранимый процесс. Будет ли работать заданное по умолчанию значение Null для параметров процесса SQL Stored?

Если это динамический sql, всегда передайте правильное количество параметров, независимо от того, является ли оно нулевым или фактическим значением, или укажите значения по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...