Supercede null导致存储过程和VBA

时间:2017-05-01 19:43:10

标签: sql sql-server vba stored-procedures

我写了一个简单的存储过程,我似乎无法覆盖空返回值。

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

我已尝试使用IF NULLIF(@serial, '') IS NULL验证该程序,但这似乎并不重要。问题是功能' can'无意中被执行(边缘情况)。我无法避免它,因为我在多个方向上使用该功能,所以我能做的最好的事情就是返回一个' 0' 0' 0' 0' 0当select语句导致null时。

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

我错过了什么?

1 个答案:

答案 0 :(得分:1)

尝试在“set @remaining =”之后输入ISNULL条件......就像这样。

            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

结果:

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

        (1 row(s) affected)


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

        (1 row(s) affected)