2014-02-20 19 views
11

Problem:
Wenn Werte in dem folgende Skript zur Verfügung gestellt werden dann wie unten ein Setup in C# ausgeführt (oder in SQL Server-Umgebung) die Werte in der Datenbank nicht aktualisieren.SQL Server gespeicherte Prozedur Nullable Parameter

Stored Procedure:

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

Wenn ich eine Ausführung dieses Skripts zu tun, wie unten, ist es keine Werte aktualisieren.

Beispiel Ausführung:

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 

Details:

Nach dem Ausführen einer (über C# -Code oder SQL Server-Umgebung) ausgeführt wird es nicht dbo.DropDownSelection.SelectedOptionID nicht aktualisiert. Ich vermute, dass es sein könnte, weil dbo.DropDownSelection.SelectedOptionID nicht Nullable ist und der Parameter, den ich benutze, um es zu setzen, ist Nullable (obwohl bei der Einstellung sollte es nie null sein). Bei der Ausführung ist der Rückgabewert 0. Wenn ich eines der Updates außerhalb der Prozedur ausführen, funktionieren sie perfekt, daher mein Verdacht, dass es mit nullfähigen Typen zu tun hat.

Frage (n):

Könnte sein, weil die Parameter der gespeicherten Prozedur nullable sind und die Felder Ich gründe nicht?

Wenn nicht, was könnte es sein?

+1

Wenn Sie diese Einfügevorgänge und Aktualisierungen in Selektionen ändern, geben Sie Daten für die angegebenen Parameter zurück? – TTeeple

+0

Ja. Ich aktualisierte meine Frage, fügte hinzu: "Wenn ich eines der Updates außerhalb der Prozedur ausführen, funktionieren sie perfekt, daher mein Verdacht, dass es mit nullfähigen Typen zu tun hat." – Shelby115

+0

1) Ich habe meine Frage ein wenig geklärt. Ich versuche nicht, Ausgabeparameter zu machen. 2) Die gespeicherte Prozedur sagt, dass sie ausgeführt wird, und sie gibt 0 zurück, aber die Werte werden nie aktualisiert. Ich bin mir nicht sicher, was du mit "via sql block" meinst. – Shelby115

Antwort

8

Es sieht so aus, als ob Sie Null für jedes Argument mit Ausnahme von PropertyValueID und DropDownOptionID übergeben, oder? Ich glaube nicht, dass irgendeine Ihrer IF-Anweisungen ausgelöst wird, wenn nur diese zwei Werte nicht-null sind. Kurz gesagt, ich denke, Sie haben einen logischen Fehler.

Other than that, würde ich zwei Dinge vorschlagen ...

Zuerst statt Tests für NULL, verwenden Sie diese Art Syntax auf, wenn Anweisungen (es ist sicherer) ...

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

Zweitens, fügen Sie vor jedem UPDATE eine sinnvolle PRINT-Anweisung hinzu. Wenn Sie den Sproc in MSSQL ausführen, können Sie sich die Nachrichten ansehen und sehen, wie weit sie tatsächlich kommen.

+0

Wow, ich fühle mich dumm. Es sollte "ELSE WENN @DropDownOptionID IST NICHT NULL" wie der Rest von ihnen sein:/Danke. – Shelby115

+10

Wie ist 'ISNULL (...' sicherer als '... IS NULL'? Es scheint, als wäre Ihr Vorschlag * weniger * sicher, weil Sie aus einem bestimmten Grund jetzt einen magischen Wert (Null) haben Wenn Sie NULL-Werte verwenden oder zulassen, ist das Testen auf "NULL" und nur auf "NULL" die sicherste Aufgabe. –

0

Sie können/sollten Ihren Parameter auf den Wert DBNull.Value setzen;

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

Oder Sie können Ihre Server-Seite auf null gesetzt und nicht passieren die param überhaupt verlassen.

Verwandte Themen