SqlParameter со значением Nullable дают ошибку в то время как ExecuteNonQuery?

Самый простой способ - использовать py-файл, а затем вызывать его из командной строки.

Внутри name_file.py поместите:

a = 10
print("Hello {}".format(a))
import math

В консольном порядке

python name_file.py

См. файл Python

22
задан Patrick Desjardins 14 May 2009 в 13:32
поделиться

2 ответа

Типы несовместимы. Попробуйте что-то вроде этого:

dbParam_au_id.Value = (object)birthday ?? DBNull.Value;
57
ответ дан 29 November 2019 в 03:34
поделиться

Если класс SqlParameter был записан правильно в первый раз ... нулевое значение C # будет обрабатываться как DBNull.Value. Это было бы интуитивно понятно, поэтому, конечно, установка значения SqlParameter равным null функционально эквивалентна его удалению из SqlParameterCollection.

Чтобы исправить эту нелепую ошибку проектирования API, создайте свой собственный метод AddParameter (с перегрузками), который принимает SqlParameterCollection, a String (имя параметра) и Object (значение параметра).

#region Add by Name/Value.
/// <summary>
/// Adds an input parameter with a name and value.  Automatically handles conversion of null object values to DBNull.Value.
/// </summary>
/// <param name="parameters">SqlParameterCollection from an SqlCommand instance.</param>
/// <param name="name">The name of the parameter to add.</param>
/// <param name="value">The value of the parameter to add.</param>
private static void AddParameter( SqlParameterCollection parameters, string name, object value )
{
    parameters.Add( new SqlParameter( name, value ?? DBNull.Value ) );
}

/// <summary>
/// Adds a parameter with a name and value.  You specify the input/output direction.  Automatically handles conversion of null object values to DBNull.Value.
/// </summary>
/// <param name="parameters">SqlParameterCollection from an SqlCommand instance.</param>
/// <param name="name">The name of the parameter to add.</param>
/// <param name="value">The value of the parameter to add.  If null, this is automatically converted to DBNull.Value.</param>
/// <param name="direction">The ParameterDirection of the parameter to add (input, output, input/output, or return value).</param>
private static void AddParameter( SqlParameterCollection parameters, string name, object value, ParameterDirection direction )
{
    SqlParameter parameter = new SqlParameter( name, value ?? DBNull.Value );
    parameter.Direction = direction;
    parameters.Add( parameter );
}
#endregion

#region Add by Name, Type, and Value.
/// <summary>
/// Adds an input parameter with a name, type, and value.  Automatically handles conversion of null object values to DBNull.Value.
/// </summary>
/// <param name="parameters">SqlParameterCollection from an SqlCommand instance.</param>
/// <param name="name">The name of the parameter to add.</param>
/// <param name="type">Specifies the SqlDbType of the parameter.</param>
/// <param name="value">The value of the parameter to add.  If null, this is automatically converted to DBNull.Value.</param>
private static void AddParameter( SqlParameterCollection parameters, string name, SqlDbType type, object value )
{
    AddParameter( parameters, name, type, 0, value ?? DBNull.Value, ParameterDirection.Input );
}

/// <summary>
/// Adds a parameter with a name, type, and value.  You specify the input/output direction.  Automatically handles conversion of null object values to DBNull.Value.
/// </summary>
/// <param name="parameters">SqlParameterCollection from an SqlCommand instance.</param>
/// <param name="name">The name of the parameter to add.</param>
/// <param name="type">Specifies the SqlDbType of the parameter.</param>
/// <param name="value">The value of the parameter to add.  If null, this is automatically converted to DBNull.Value.</param>
/// <param name="direction">The ParameterDirection of the parameter to add (input, output, input/output, or return value).</param>
private static void AddParameter( SqlParameterCollection parameters, string name, SqlDbType type, object value, ParameterDirection direction )
{
    AddParameter( parameters, name, type, 0, value ?? DBNull.Value, direction );
}
#endregion

#region Add by Name, Type, Size, and Value.
/// <summary>
/// Adds an input parameter with a name, type, size, and value.  Automatically handles conversion of null object values to DBNull.Value.
/// </summary>
/// <param name="parameters">SqlParameterCollection from an SqlCommand instance.</param>
/// <param name="name">The name of the parameter to add.</param>
/// <param name="type">Specifies the SqlDbType of the parameter.</param>
/// <param name="size">Specifies the size of the parameter for parameter types of variable size.  Set to zero to use the default size.</param>
/// <param name="value">The value of the parameter to add.  If null, this is automatically converted to DBNull.Value.</param>
private static void AddParameter( SqlParameterCollection parameters, string name, SqlDbType type, int size, object value )
{
    AddParameter( parameters, name, type, size, value ?? DBNull.Value, ParameterDirection.Input );
}

/// <summary>
/// Adds a parameter with a name, type, size, and value.  You specify the input/output direction.  Automatically handles conversion of null object values to DBNull.Value.
/// </summary>
/// <param name="parameters">SqlParameterCollection from an SqlCommand instance.</param>
/// <param name="name">The name of the parameter to add.</param>
/// <param name="type">Specifies the SqlDbType of the parameter.</param>
/// <param name="size">Specifies the size of the parameter for parameter types of variable size.  Set to zero to use the default size.</param>
/// <param name="value">The value of the parameter to add.  If null, this is automatically converted to DBNull.Value.</param>
/// <param name="direction">The ParameterDirection of the parameter to add (input, output, input/output, or return value).</param>
private static void AddParameter( SqlParameterCollection parameters, string name, SqlDbType type, int size, object value, ParameterDirection direction )
{
    SqlParameter parameter;
    if (size < 1)
        parameter = new SqlParameter( name, type );
    else
        parameter = new SqlParameter( name, type, size );
    parameter.Value = value ?? DBNull.Value;
    parameter.Direction = direction;
    parameters.Add( parameter );
}
#endregion

Как вы можете видеть, внутри этого метода (и перегрузок), где значение уже введено как объект, я использую «значение ?? DBNull. Value "для обеспечения соблюдения правила null = DBNull.Value.

Теперь, когда вы передаете ссылки на нулевые объекты или типы, допускающие значение null, без значений в метод AddParameter, вы получаете ожидаемое интуитивно понятное поведение, в котором DBNull. В запрос передается значение.

Я не могу себе представить, почему API был реализован как есть, потому что, если бы я хотел, чтобы параметр игнорировался, я бы не ДОБАВЛЯЛ его, а затем УСТАНАВЛИВАЮ его значение равным нулю. Я бы либо НЕ добавлял его в первую очередь, либо УДАЛЯЛ его из SqlParameterCollection. Если я ДОБАВЛЯЮ параметр и УСТАНАВЛЯЮ его значение (даже если установлено значение null), я ожидаю, что он будет ИСПОЛЬЗОВАН в запросе, я ожидаю, что null будет означать нулевое значение.

Я слышал, что они не реализовали его, "правильный" способ по соображениям производительности, но это нелепо, как показано, потому что вызов метода SqlParameterCollection.AddWithValue все равно преобразует все в объект, а преобразование экземпляра Nullable без значения в нулевой объект является неотъемлемой частью языка C #, который является вообще не хит производительности. Microsoft действительно должна это исправить.

15
ответ дан 29 November 2019 в 03:34
поделиться