我无法在 SQL Server 中使用我的声明@AverageValue

I can't use my declare @AverageValue in SQL Server

提问人:M.Eren 提问时间:11/10/2023 最后编辑:marc_sM.Eren 更新时间:11/10/2023 访问量:56

问:

我在SQL Server中有一个变量。它的名字是.@AverageValue

EXEC sp_executesql @DynamicSQL, N'@AverageValue FLOAT OUTPUT', @AverageValue OUTPUT 

在这一行中,我可以看到结果并有一个值。像 2.1135432 一样,它对我有用,很好,但我必须在其他部分使用它。@AverageValue

SELECT CAST(@average AS FLOAT) AS OutputMessage

IF @AverageValue > 1
BEGIN
    SET @isLowAverage = 1
END

在此行上为 null。所以我需要使用 的值,但是当它为 null 时,我无法设置 .但是当我执行它时,它不是空的。问题是什么?这是我的存储过程:@AverageValue@AverageValue@isLowAverage

AS
BEGIN
    DECLARE @StartDate DATETIME = DATEADD(HOUR, -24, GETDATE())
    DECLARE @ParameterIds NVARCHAR(100) = '2246,2247'
    DECLARE @isLowAverage BIT = 0
    DECLARE @sendMessage bit = 0,
            @toMailAddresses nvarchar(MAX)='',  
            @mailSubject nvarchar(MAX)='',  
            @mailBody nvarchar(MAX)='',
            @roleId int = 22222222,
            @tableHtml nvarchar(max),
            @departman nvarchar(max),
            @location nvarchar(max),
            @date nvarchar(max),
            @average nvarchar(max),
            @AverageValue FLOAT

    DECLARE @ParameterTable TABLE (ParameterId INT)

    INSERT INTO @ParameterTable
        SELECT CAST(value AS INT) AS ParameterId
        FROM STRING_SPLIT(@ParameterIds, ',')

    DECLARE @ParameterId INT
    DECLARE @DynamicSQL NVARCHAR(MAX)

    DECLARE ParameterCursor CURSOR FOR
        SELECT ParameterId FROM @ParameterTable

    OPEN ParameterCursor
    FETCH NEXT FROM ParameterCursor INTO @ParameterId

    WHILE @@FETCH_STATUS = 0
    BEGIN
        SET @DynamicSQL = 'SELECT ''' + CAST(@ParameterId AS NVARCHAR) + ''' AS ParameterId, AVG(CAST([parameterValue] AS FLOAT)) AS AverageValue FROM [SPCParametersDataT] WHERE parameterId = ' + CAST(@ParameterId AS NVARCHAR) + ' AND [date] >= ''' + CONVERT(NVARCHAR, @StartDate, 121) + ''''
        
      EXEC sp_executesql @DynamicSQL, N'@AverageValue FLOAT OUTPUT', @AverageValue OUTPUT 

        SELECT CAST(@average AS FLOAT) AS OutputMessage

        IF @AverageValue > 1
        BEGIN
            SET @isLowAverage = 1
            SET @date = GETDATE()
        END

        FETCH NEXT FROM ParameterCursor INTO @ParameterId
    END

    CLOSE ParameterCursor
    DEALLOCATE ParameterCursor
  
    SELECT 'isLowAverage: ' + CAST(@isLowAverage AS NVARCHAR) AS OutputMessage

我需要在这条线上工作。我需要该值,但它返回为 null。但它不是上面一行的空

sql-server 存储过程

评论

0赞 siggemannen 11/10/2023
动态 sql 参数不会以这种方式分配。你需要有动态的 sql。我认为你应该先阅读一些关于动态sql的教程select @param = 1234
2赞 Thom A 11/10/2023
为什么要注入参数而不是参数化它们?sys.sp_executesql

答:

0赞 Squirrel 11/10/2023 #1

您需要将计算出的平均值分配给变量

SET @DynamicSQL = 'SELECT @AverageValue = AVG(CAST([parameterValue] AS FLOAT)) FROM [SPCParametersDataT] WHERE parameterId = ' + CAST(@ParameterId AS NVARCHAR) + ' AND [date] >= ''' + CONVERT(NVARCHAR, @StartDate, 121) + ''''

EXEC sp_executesql @DynamicSQL, N'@AverageValue FLOAT OUTPUT', @AverageValue OUTPUT 

使用动态查询的正确方法是对所有参数使用参数,而不是将(@ParameterId 和 @StartDate)连接到查询中。

您的动态查询应为

SET @DynamicSQL = 'SELECT @AverageValue = AVG(CAST([parameterValue] AS FLOAT)) FROM [SPCParametersDataT] WHERE parameterId = @ParameterId AND [date] >= @StartDate'

EXEC sp_executesql 
       @DynamicSQL, 
       N'@AverageValue FLOAT OUTPUT, @parameterId INT, @StartDate datetime', 
       @AverageValue OUTPUT, @parameterId, @StartDate

实际上,您的查询中根本没有任何内容。您可以通过简单的选择查询完成相同的操作dyanamic

SELECT @AverageValue = AVG(CAST([parameterValue] AS FLOAT)) 
FROM   [SPCParametersDataT] 
WHERE  parameterId = @ParameterId 
AND    [date] >= @StartDate

不确定你想做什么,但你可能也不需要光标和while循环。

评论

0赞 M.Eren 11/20/2023
谢谢你的帮助。我可以通过一个简单的选择查询来做到这一点