2017-05-01 1 views
1

Ich schrieb eine einfache gespeicherte Prozedur, die ich scheinbar nicht null Rückgabewerte überschreiben kann.Supercede null Ergebnisse in gespeicherten Prozedur und VBA

ALTER PROC [dbo].[rt_sp_rstk_OpticComplete] 
    @serial varchar(50) OUTPUT,  
    @remaining int OUTPUT 
AS 
    SET NOCOUNT ON 
BEGIN 
    UPDATE [ROBOTICS_OPTICS_MECHUAT].[dbo].[RESTOCK_OPTICS] 
    SET [SELECTED] = 'False', 
     [COMPLETED] = 'True' 
    WHERE [SERIAL_NUMBER] = @serial  

    UPDATE [ROBOTICS_OPTICS_MECHUAT].[dbo].[RESTOCK_JOB_QUEUE] 
    SET [QUANTITY_REMAINING] = [QUANTITY_REMAINING] - 1 
    WHERE [SELECTED] = 'True' 

    SET @remaining = (SELECT [QUANTITY_REMAINING] 
         FROM [ROBOTICS_OPTICS_MECHUAT].[dbo].[RESTOCK_JOB_QUEUE] 
         WHERE [SELECTED] = 'True') 

    RETURN ISNULL(@remaining, 0) 
END 

Ich habe versucht, das Verfahren mit IF NULLIF(@serial, '') IS NULL für eine gute Maßnahme Validierung aber es keine Rolle zu spielen. Das Problem ist, dass die Funktion 'can' (Randfall) versehentlich ausgeführt werden kann. Ich kann es nicht wirklich vermeiden, weil ich die Funktion in mehrere Richtungen verwende, also ist das Beste, was ich tun kann, einfach eine '0' zurückzugeben, wenn die select-Anweisung eine Null ergibt.

Function restockOpticComplete(serial As String) As Integer 
    Dim remaining As Integer 
    Dim opticSerNo As String 

    errorPosition = "queryForOptics.restockOpticComplete" 
    On Error GoTo errorTrap 
    Err.Clear 

    Set conn = New ADODB.Connection 
    Set cmd = New ADODB.Command 
    constr = "Provider=sqloledb;data source=i.p.add.ress;initial catalog=CATALOG;user id=USER;password=PASS" 
    conn.Open constr 
    cmd.ActiveConnection = conn 

    With cmd 
     .ActiveConnection = conn 
     .CommandType = adCmdStoredProc 
     .CommandText = "rt_sp_rstk_OpticComplete" 
     .CommandTimeout = 2 
     .NamedParameters = True 
     .Parameters.Append .CreateParameter("@serial", adVarChar, adParamInputOutput, 50, serial) 
     .Parameters.Append .CreateParameter("@remaining", adInteger, adParamOutput, , 0) 
     .execute 
    End With 

    Set eTag = ThisDisplay.tagDisplay.item("_Eventwatcher").EGroup.item("Restock\activeOpticSerial") 
    eTag.Value = "" 
    Set eTag = ThisDisplay.tagDisplay.item("_Eventwatcher").EGroup.item("Restock\activeOpticStack") 
    eTag.Value = 0 
    Set eTag = ThisDisplay.tagDisplay.item("_Eventwatcher").EGroup.item("Restock\activeOpticTray") 
    eTag.Value = 0 
    Set eTag = ThisDisplay.tagDisplay.item("_Eventwatcher").EGroup.item("Restock\activeOpticPosition") 
    eTag.Value = 0 
    remaining = cmd.Parameters("@remaining").Value 
    Set eTag = ThisDisplay.tagDisplay.item("_Eventwatcher").EGroup.item("Restock\activeJobRemaining") 
    eTag.Value = remaining 

    restockOpticComplete = remaining 

    GoTo cleanExit 

cleanExit: 
    On Error Resume Next 
    conn.Close 

    Exit Function 

errorTrap: 
    LogDiagnosticsMessage "Restock.gfx, Position: " & errorPosition & " , Error Code: [ " & Hex(Err.Number) & "], Description: " & Err.Description & "" 
    Resume cleanExit 

End Function 

Was fehlt mir?

+0

Ahh den VBA-Teil verpasst ... so was ist die eigentliche Frage? Sie haben ein Problem mit etwas, aber ich habe keine Ahnung, was das Problem ist. –

+0

@SeanLange Obwohl ich ISNULL benutze, bekomme ich immernoch Nullwerte. – Jaberwocky

+0

Sie verwenden den verbleibenden Wert, aber in Ihrem Code stellen Sie ihn nicht auf Null ein. Sie geben stattdessen eine Nummer zurück. Die einfachste Lösung ist, das Wort "RETURN" in "SELECT" zu ändern. So wie es codiert ist, müssten Sie RETURN_VALUE überprüfen, aber ehrlich gesagt ist die Verwendung eines Ausgabeparameters die bevorzugte Methode dafür. –

Antwort

1

Versuchen Sie die ISNULL-Bedingung nach "set @remaining =" ... etwas wie folgt.

  ALTER PROC [dbo].[rt_sp_rstk_OpticComplete] 
       @serial varchar(50) OUTPUT,  
       @remaining int OUTPUT 
      AS 
       SET NOCOUNT ON 
      BEGIN 
       UPDATE [ROBOTICS_OPTICS_MECHUAT].[dbo].[RESTOCK_OPTICS] 
       SET [SELECTED] = 'False', 
        [COMPLETED] = 'True' 
       WHERE [SERIAL_NUMBER] = @serial  

       UPDATE [ROBOTICS_OPTICS_MECHUAT].[dbo].[RESTOCK_JOB_QUEUE] 
       SET [QUANTITY_REMAINING] = [QUANTITY_REMAINING] - 1 
       WHERE [SELECTED] = 'True' 

       SET @remaining = ISNULL((SELECT [QUANTITY_REMAINING] 
            FROM [ROBOTICS_OPTICS_MECHUAT].[dbo].[RESTOCK_JOB_QUEUE] 
            WHERE [SELECTED] = 'True'),0) 

       RETURN @remaining 
      END 

TEST

   --- test 1 
       CREATE PROC [dbo].[rt_sp_rstk_OpticComplete_test] 
        @val INT, 
        @remaining int OUTPUT 
       AS 
        SET NOCOUNT ON 
       BEGIN 
        SET @remaining = @val 
        RETURN isnull(@remaining,0) 

       END 

       GO 

       DECLARE @remaining INT 
       EXEC [dbo].[rt_sp_rstk_OpticComplete_test]null,@remaining OUTPUT 

       SELECT @remaining 

       GO 

       DROP PROC [dbo].[rt_sp_rstk_OpticComplete_test] 
       GO 

       --- test 2 
       CREATE PROC [dbo].[rt_sp_rstk_OpticComplete_test] 
        @val INT, 
        @remaining int OUTPUT 
       AS 
        SET NOCOUNT ON 
       BEGIN 


        SET @remaining = isnull(@val,0) 
        RETURN @remaining 
       END 

       GO 


       DECLARE @remaining INT 
       EXEC [dbo].[rt_sp_rstk_OpticComplete_test]null,@remaining OUTPUT 
       SELECT @remaining 

       GO 

       DROP PROC [dbo].[rt_sp_rstk_OpticComplete_test] 
       GO 

Ergebnis:

 ----------- 
     NULL 

     (1 row(s) affected) 


     ----------- 
     0 

     (1 row(s) affected) 
+0

Ich werde damit spielen, wenn ich zu diesem Teil meines Codes zurückkomme. Ich könnte schwören, ich habe es schon versucht, aber wer erinnert sich: P – Jaberwocky

Verwandte Themen