Динамическая хранимая процедура и разбиение на страницы

У меня есть то, что, как мне кажется, описывается как динамическая хранимая процедура, сокращенная версия приведена ниже.

[dbo].[spImageCard_GetStatusByCountryAlphabetically]
            @WhereClause nvarchar(2000)
                    AS
                    BEGIN
                    SET NOCOUNT ON
                    Declare @SelectStatement nvarchar(1800)
                    Declare @OrderClause nvarchar(200)
                    Declare @FullStatement nvarchar(4000)
                    Set @SelectStatement = 'Select Distinct [StampTable].StampId,[SeriesTable].Series, [StampTable].CatalogueNo, [CountryTable].Country, [ImageTable].Image From StampTable
                    left Join SeriesTable on StampTable.Series = SeriesTable.SeriesId
                    left Join ImageTable on StampTable.Image = ImageTable.ImageId
                    left Join CountryTable on StampTable.Country = CountryTable.CountryId
                    left Join StampQuantatiesTable on StampTable.StampId = StampQuantatiesTable.StampId
                    Left Join QuantatiesTable on StampQuantatiesTable.QuantatiesId = QuantatiesTable.QuantatiesId
                    Left Join [StatusTable] on  QuantatiesTable.StatusId = StatusTable.StatusId '
                    Set @OrderClause = 'ORDER BY [CountryTable].Country, [StampTable].CatalogueNo'
                    Set @FullStatement = @SelectStatement + @WhereClause + @OrderClause
                    
                    Execute (@FullStatement)

Это работает, как и ожидалось, при вызове следующего

Declare @WhereClause Nvarchar(2000)
                    Set @WhereClause= 'WHERE StatusTable.Status IN (''Have'',''Want'')
                    AND [CountryTable].Country IN (''Aden'')'
                    Execute spImageCard_GetStatusByCountryAlphabetically @WhereClause = @WhereClause

Сейчас я пытаюсь представить то, что, по моему мнению, относится к нумерации страниц, мой упрощенный автономный рабочий пример для этого:

[dbo].[spPageReturnTest]
            @PageNumber As INT,@RowsInPage As INT
                    AS
                    BEGIN
                    SET NOCOUNT ON
Select stampid, CatalogueNo From StampTable
Order by Stampid
Offset (@PageNumber-1)*@RowsInPage ROWS
Fetch Next @RowsInPage Rows Only

К сожалению, когда я пытаюсь ввести соответствующие части (@Parameters и строки Offset и Fetch), я получаю множество ошибок. Любая помощь будет высоко оценена

Моя последняя версия, учитывающая ваши комментарии о sqlString и cast, выглядит следующим образом:

[dbo].[spImageCard_GetStatusByCountryAlphabetically]
            @WhereClause nvarchar(2000), @PageNumber INT,@RowsInPage INT
                    AS
                    BEGIN
                    SET NOCOUNT ON
                    Declare @SelectStatement nvarchar(1650)
                    Declare @OrderClause nvarchar(200)
                    Declare @FullStatement nvarchar(4000)
                    Declare @Pagination nvarchar(150)
                    Declare @PageNumberString nvarchar(4)
                    Declare @RowsInPageString nvarchar(4)
                    Set @PageNumberString = Cast(@PageNumber As nvarchar(4))
                    Set @RowsInPageString = cast(@RowsInPage As nvarchar(4))
                    Set @SelectStatement = 'Select Distinct [StampTable].StampId,[SeriesTable].Series, [StampTable].CatalogueNo, [CountryTable].Country, [ImageTable].Image From StampTable
                    left Join SeriesTable on StampTable.Series = SeriesTable.SeriesId
                    left Join ImageTable on StampTable.Image = ImageTable.ImageId
                    left Join CountryTable on StampTable.Country = CountryTable.CountryId
                    left Join StampQuantatiesTable on StampTable.StampId = StampQuantatiesTable.StampId
                    Left Join QuantatiesTable on StampQuantatiesTable.QuantatiesId = QuantatiesTable.QuantatiesId
                    Left Join [StatusTable] on  QuantatiesTable.StatusId = StatusTable.StatusId '
                    Set @OrderClause = 'ORDER BY [CountryTable].Country, [StampTable].CatalogueNo'
                    Set @Pagination = 'Offset (('+@PageNumberString+'-1)*'+@RowsInPageString+') ROWS Fetch Next '+@RowsInPageString+' Rows Only'
                    Set @FullStatement = @SelectStatement + @WhereClause + @OrderClause + @Pagination
                    Execute sp_executesql @FullStatement

И моя процедура вызова

Declare @WhereClause Nvarchar(2000)
Declare @PageNumber INT
Declare @RowsInPage INT
                        Set @WhereClause= 'WHERE StatusTable.Status IN (''Have'',''Want'')
                    AND [CountryTable].Country IN (''Aden'')'
                        Execute spImageCard_GetStatusByCountryAlphabetically @WhereClause = @WhereClause,@PageNumber=1,@RowsInPage=3

Ошибка, которую я получаю, выглядит следующим образом

Сообщение 102, уровень 15, состояние 1, строка 8 Неверный синтаксис рядом с «ROWS». Сообщение 153, уровень 15, состояние 2, строка 8. Недопустимое использование параметра «Далее» в операторе FETCH.

Обратите внимание, что я также пробовал N'в начале каждой строки, и ошибка та же самая.


person StephenH    schedule 01.12.2020    source источник
comment
Вы должны взглянуть на эту ссылку: stackoverflow.com/a/11669590/9294131. В основном вам нужно создать строку sql, а затем запустить ее с параметрами   -  person Avjol Sakaj    schedule 02.12.2020
comment
Спасибо за ваш ответ, но я пробовал варианты 'Set @Pagination = 'Offset'''+((@PageNumber-1)*@RowsInPage)+''' ROWS Fetch Next '''+@RowsInPage+''' Только строки '', но безуспешно. Что я делаю не так?   -  person StephenH    schedule 02.12.2020
comment
Какая у вас ошибка? Вы пытались преобразовать параметры CAST в varchar?   -  person Avjol Sakaj    schedule 03.12.2020
comment
Спасибо за ваши предложения, я обновил свой код вопроса, чтобы отразить их вместе с полученной ошибкой.   -  person StephenH    schedule 03.12.2020
comment
Вероятно, правильнее будет назвать хранимую процедуру, выполняющую динамический SQL. Сама процедура не является динамической.   -  person Dale K    schedule 06.12.2020


Ответы (1)


Мне, наконец, удалось решить эту проблему, и я не могу поверить, насколько просто было исправить ошибку, как только я ее идентифицировал, но в равной степени и насколько легко эту ошибку сделать. При построении строки убедитесь, что в конце каждого из строковых параметров есть пробел, иначе в моем случае, когда @OrderClause и @Pagination были объединены, он читался как

ORDER BY [CountryTable].Country, [StampTable].CatalogueNoOffset (('+@PageNumberString+'-1)*'+@RowsInPageString+') ROWS Fetch Next '+@RowsInPageString+' Rows Only']

Нет пробела между CatalogueNo и Offset Когда я просматривал многие из моих сохраненных ранее работ, это было фундаментальной проблемой, но в разных и часто в нескольких местах.

person StephenH    schedule 04.12.2020
comment
print(@FullStatement) — ваш лучший друг при отладке динамического SQL — тогда у вас будет статический SQL для отладки. - person Dale K; 06.12.2020