web-dev-qa-db-ja.com

ストアドプロシージャエラー「スカラー変数を宣言する必要があります」

動的SQLを含むストアドプロシージャを作成しようとしています。 procは5つの変数を受け取ります。そのうち3つは列とフィールドの名前で、もう2つはOFFSETとFETCH NEXTの部分です。最後の2つの変数でこのエラーが発生し続けます。

メッセージ137、レベル15、状態2、行34スカラー変数 "@numOfOffset"を宣言する必要があります。メッセージ137、レベル15、状態2、行34スカラー変数 "@numOfRows"を宣言する必要があります。

私はいくつかの助けに感謝します

IF (SELECT 1 FROM sys.procedures WHERE [name] = 'sp_targil1') = 1
    DROP PROCEDURE sp_targil1;
GO

CREATE PROCEDURE sp_targil1 (@tableName varchar(30), @fieldNameAggBy varchar(30), @fieldNameToAggOn varchar(30)
    ,  @numOfOffset int, @numOfRows int
    )
AS
BEGIN
    DECLARE @query1 varchar(500)
    DECLARE @qaeryMain varchar(500)
    DECLARE @maxNumberOfRows int

    SET @qaeryMain = 
    '
    SELECT ' + @fieldNameAggBy + ', SUM(' + @fieldNameToAggOn + ') AS ' + @fieldNameToAggOn + '_Sum_By_' + @fieldNameAggBy +
    ' FROM ' + @tableName +
    ' GROUP BY ' + @fieldNameAggBy + 
    ' ORDER BY SUM(' + @fieldNameToAggOn + ') DESC OFFSET @numOfOffset - 1 ROWS FETCH NEXT @numOfRows ROWS ONLY'
    PRINT @qaeryMain
    EXECUTE (@qaeryMain)
END

1
user183765

動的SQLステートメントのコンテキスト内で@numOfOffsetまたは@numOfRows変数を宣言していません。 PRINT @qaeryMainステートメントの出力をコピーすると、DECLAREステートメントが明確に欠けていることに気付くでしょう。これがエラーが発生する理由です。

コードを次のように変更すると、未定義の変数ではなくDSQLステートメント内でリテラルが指定されるため、問題が解決されます。

IF (SELECT 1 FROM sys.procedures WHERE [name] = 'sp_targil1') = 1
    DROP PROCEDURE sp_targil1;
GO

CREATE PROCEDURE sp_targil1 (@tableName varchar(30), @fieldNameAggBy varchar(30), @fieldNameToAggOn varchar(30)
    ,  @numOfOffset int, @numOfRows int
    )
AS
BEGIN
    DECLARE @query1 varchar(500)
    DECLARE @qaeryMain varchar(500)
    DECLARE @maxNumberOfRows int

    SET @qaeryMain = 
    '
    SELECT ' + @fieldNameAggBy + ', SUM(' + @fieldNameToAggOn + ') AS ' + @fieldNameToAggOn + '_Sum_By_' + @fieldNameAggBy +
    ' FROM ' + @tableName +
    ' GROUP BY ' + @fieldNameAggBy + 
    ' ORDER BY SUM(' + @fieldNameToAggOn + ') DESC OFFSET ' + CAST(@numOfOffset AS VARHCAR(50)) + ' - 1 ROWS FETCH NEXT ' + CAST(@numOfRowsAS VARHCAR(50)) + ' ROWS ONLY'
    PRINT @qaeryMain
    EXECUTE (@qaeryMain)
END
5
John Eisbrener