web-dev-qa-db-fra.com

Procédure stockée SQL Server Paramètre nul

Problème:
Lorsque des valeurs sont fournies au script suivant, puis exécutées à l'aide d'une configuration en C # comme ci-dessous (ou dans un environnement SQL Server), les valeurs ne sont pas mises à jour dans la base de données.

Procédure stockée:

-- 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

Quand je fais une exécution de ce script, comme ci-dessous, il ne met à jour aucune valeur.

Exemple d'exécution:

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

Détails:

Après avoir exécuté une exécution (via du code C # ou un environnement SQL Server), il ne met pas à jour dbo.DropDownSelection.SelectedOptionID. Je suppose que c'est peut-être parce que dbo.DropDownSelection.SelectedOptionID n'est pas nullable et le paramètre que j'utilise pour le définir est nullable (malgré cela, lors de la définition, il ne devrait jamais être nul). Lors de l'exécution, la valeur de retour est 0. Si j'exécute l'une des mises à jour en dehors de la procédure, elles fonctionnent parfaitement, d'où mon soupçon que cela a à voir avec les types null-able.

Question (s):

Cela peut-il être dû au fait que les paramètres de la procédure stockée peuvent être annulés et que les champs que je définis ne le sont pas?

Sinon, que pourrait-il être?

17
Shelby115

Il semble que vous passiez Null pour chaque argument, à l'exception de PropertyValueID et DropDownOptionID, non? Je ne pense pas que l'une de vos instructions IF se déclenchera si seulement ces deux valeurs ne sont pas nulles. Bref, je pense que vous avez une erreur logique.

A part ça, je suggérerais deux choses ...

Tout d'abord, au lieu de tester NULL, utilisez ce type de syntaxe sur vos instructions if (c'est plus sûr) ...

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

Deuxièmement, ajoutez une instruction PRINT significative avant chaque UPDATE. De cette façon, lorsque vous exécutez le sproc dans MSSQL, vous pouvez consulter les messages et voir jusqu'où cela va réellement.

10
Ash8087

Vous pouvez/devez définir la valeur de votre paramètre sur DBNull.Value;

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

Ou vous pouvez laisser votre côté serveur défini sur null et ne pas passer du tout le param.

0
user1040975