Подтвердить что ты не робот

Хранимая процедура SQL Server Параметр Nullable

Проблема:
Когда значения предоставляются для следующего script, затем выполняются с использованием настройки в С#, как показано ниже (или в среде SQL Server), значения не обновляются в базе данных.

Сохраненная процедура:

-- Updates the Value of any type of PropertyValue
-- (Type meaining simple Value, UnitValue, or DropDown)
CREATE PROCEDURE [dbo].[usp_UpdatePropertyValue]
    @PropertyValueID int,
    @Value varchar(max) = NULL,
    @UnitValue float = NULL,
    @UnitOfMeasureID int = NULL,
    @DropDownOptionID int = NULL
AS
BEGIN   
    -- If the Property has a @Value, Update it.
    IF @Value IS NOT NULL
    BEGIN
        UPDATE [dbo].[PropertyValue]
        SET
            Value = @Value
        WHERE
            [dbo].[PropertyValue].[ID] = @PropertyValueID
    END
    -- Else check if it has a @UnitValue & UnitOfMeasureID
    ELSE IF @UnitValue IS NOT NULL AND @UnitOfMeasureID IS NOT NULL
    BEGIN
        UPDATE [dbo].[UnitValue]
        SET
            UnitValue = @UnitValue,
            UnitOfMeasureID = @UnitOfMeasureID
        WHERE
            [dbo].[UnitValue].[PropertyValueID] = @PropertyValueID          
    END
    -- Else check if it has just a @UnitValue
    ELSE IF @UnitValue IS NOT NULL AND @UnitOfMeasureID IS NULL
    BEGIN
        UPDATE [dbo].[UnitValue]
        SET
            UnitValue = @UnitValue
        WHERE
            [dbo].[UnitValue].[PropertyValueID] = @PropertyValueID  
    END
    -- Else check if it has a @DropDownSelection to update.
    ELSE IF @DropDownOptionID IS NULL
    BEGIN
        UPDATE [dbo].[DropDownSelection]
        SET
            SelectedOptionID = @DropDownOptionID
        WHERE
            [dbo].[DropDownSelection].[PropertyValueID] = @PropertyValueID
    END
END

Когда я выполняю выполнение этого script, как показано ниже, он не обновляет никаких значений.

Пример выполнения:

String QueryString = "EXEC [dbo].[usp_UpdatePropertyValue] @PropertyValueID, @Value, @UnitValue, @UnitOfMeasureID, @DropDownOptionID";
SqlCommand Cmd = new SqlCommand(QueryString, this._DbConn);

Cmd.Parameters.Add(new SqlParameter("@PropertyValueID", System.Data.SqlDbType.Int));
Cmd.Parameters.Add(new SqlParameter("@Value", System.Data.SqlDbType.Int));
Cmd.Parameters.Add(new SqlParameter("@UnitValue", System.Data.SqlDbType.Int));
Cmd.Parameters.Add(new SqlParameter("@UnitOfMeasureID", System.Data.SqlDbType.Int));
Cmd.Parameters.Add(new SqlParameter("@DropDownOptionID", System.Data.SqlDbType.Int));

Cmd.Parameters["@PropertyValueID"].Value = Property.Value.ID; // 1
Cmd.Parameters["@Value"].IsNullable = true;
Cmd.Parameters["@Value"].Value = DBNull.Value;
Cmd.Parameters["@UnitValue"].IsNullable = true;
Cmd.Parameters["@UnitValue"].Value = DBNull.Value;
Cmd.Parameters["@UnitOfMeasureID"].IsNullable = true;
Cmd.Parameters["@UnitOfMeasureID"].Value = DBNull.Value;
Cmd.Parameters["@DropDownOptionID"].IsNullable = true;
Cmd.Parameters["@DropDownOptionID"].Value = 2; // Current Value in DB: 3

Детали:

После запуска выполнения (через код С# или среду SQL Server) он не обновляет dbo.DropDownSelection.SelectedOptionID. Я предполагаю, что это может быть из-за того, что dbo.DropDownSelection.SelectedOptionID не является нулевым, а параметр, который я использую для его установки, является нулевым (несмотря на то, что при настройке он никогда не должен быть нулевым). После выполнения возвращаемое значение равно 0. Если я запустил одно из обновлений вне процедуры, они работают отлично, поэтому мое подозрение, что оно связано с нулевыми типами.

Вопрос (ы):

Может ли это быть из-за того, что параметры хранимой процедуры имеют значение NULL, а поля, которые я устанавливаю, не являются?

Если нет, что это может быть?

4b9b3361

Ответ 1

Похоже, вы проходите в Null для каждого аргумента, кроме PropertyValueID и DropDownOptionID, правильно? Я не думаю, что какие-либо из ваших IF-операторов будут срабатывать, если только эти два значения не являются нулевыми. Короче говоря, я думаю, что у вас есть логическая ошибка.

Кроме этого, я бы предложил две вещи...

Во-первых, вместо тестирования для NULL используйте этот вид синтаксиса для операторов if (это безопаснее)...

    ELSE IF ISNULL(@UnitValue, 0) != 0 AND ISNULL(@UnitOfMeasureID, 0) = 0

Во-вторых, добавьте содержательную инструкцию PRINT перед каждым UPDATE. Таким образом, когда вы запускаете sproc в MSSQL, вы можете посмотреть сообщения и посмотреть, как далеко он на самом деле становится.

Ответ 2

Вы можете/должны установить свой параметр в значение DBNull.Value;

if (variable == "")
{
     cmd.Parameters.Add("@Param", SqlDbType.VarChar, 500).Value = DBNull.Value;
}
else
{
     cmd.Parameters.Add("@Param", SqlDbType.VarChar, 500).Value = variable;
}

Или вы можете оставить свой серверный сервер равным нулю и вообще не передать параметр.