Динамична съхранена процедура и страниране

Имам това, което според мен е описано като динамична съхранена процедура, съкратена версия е по-долу

[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

Грешката, която получавам, е следната

Msg 102, ниво 15, състояние 1, ред 8 Неправилен синтаксис близо до „РЕДОВЕ“. Съобщение 153, ниво 15, състояние 2, ред 8 Невалидно използване на опцията Next в оператора 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