CHill60
Я публикую более полный ответ, чтобы закончить это и в интересах всех остальных, кто столкнется с этим...
Есть несколько способов получить "номер строки" в этом случае, но, к сожалению, вы ограничены функцией SQL, где
Цитата:
Оконные функции могут появляться только в предложениях SELECT или ORDER BY.
А это значит, что ты не можешь сделать что-то подобное:
SELECT Country, CountryCode
FROM Country
WHERE ROW_NUMBER() OVER (ORDER BY CountryCode) > 4
Чтобы преодолеть эту проблему, вы можете использовать общее табличное выражение или для большей гибкости временную таблицу или табличную переменную, например
CREATE PROCEDURE [dbo].[SP3]
@param int
AS
BEGIN
SET NOCOUNT ON;
DECLARE @T TABLE (rn INT, Country varchar(30), CountryCode int)
INSERT INTO @T
SELECT ROW_NUMBER() OVER (ORDER BY CountryCode), Country, CountryCode
FROM Country
SELECT TOP 5 Country, CountryCode from @T WHERE rn > @param
RETURN (SELECT MAX(rn) FROM @T WHERE rn > @param AND rn <= @param + 5)
END
GO
Вы даже можете иметь столбец идентификатора в этой табличной переменной и вообще опустить функцию ROW_NUMBER (хотя вам все равно понадобится ORDER BY), например.
CREATE PROCEDURE [dbo].[SP2]
@param int
AS
BEGIN
SET NOCOUNT ON;
DECLARE @T TABLE (rn INT IDENTITY(1,1), Country varchar(30), CountryCode int)
INSERT INTO @T
SELECT Country, CountryCode
FROM Country
ORDER BY Country
SELECT TOP 5 Country, CountryCode from @T WHERE rn > @param
RETURN (SELECT MAX(rn) FROM @T WHERE rn > @param AND rn <= @param + 5)
END
GO
Затем вы можете вызвать хранимую процедуру следующим образом:
DECLARE @nextValue int = 0
EXEC @nextValue = dbo.SP2 @nextValue
exec @nextValue = dbo.SP2 @nextValue
EXEC @nextValue = dbo.SP2 @nextValue
exec @nextValue = dbo.SP2 @nextValue
Для моих данных (см. ниже) Я получаю запросы, возвращающие 5 записей, 5 записей, 4 записи, а затем 0 записей.
Кстати именно поэтому я и воспользовался
WHERE rn > @param AND rn <= @param + 5
для возвращаемого значения из обоих моих SPs ... количество записей не может делиться точно на 5 (или любое другое число, которое вы выберете). Если другие пользователи добавляют данные в таблицу при выполнении этих запросов, вы хотите убедиться, что случайно не пропустите ни одной строки, используя
RETURN @param + 5
Для полноты картины вот данные, которые я использовал для проверки этих примеров:
CREATE TABLE [dbo].[Country](
[id] [int] NULL,
[Country] [varchar](30) NULL,
[CountryCode] [int] NULL,
[RatePerMin] [decimal](15, 2) NULL
) ON [PRIMARY]
INSERT INTO Country VALUES
(248,'Nepal' ,97 ,3.20),
(1, 'Afghanistan' ,93 ,4.00),
(2, 'Albania' ,355 ,3.50),
(3, 'Algeria' ,213 ,2.20),
(4, 'American Samoa' ,1684,2.00),
(5, 'Andorra' ,376 ,4.20),
(6, 'Angola' ,244 ,4.20),
(7, 'Anguilla' ,1264,4.50),
(8, 'Antarctica/Norfolk Island',672 ,5.00),
(9, 'Antigua and Barbuda' ,1268,4.50),
(10, 'Sudan' ,249 ,1.40),
(11, 'Qatar' ,974 ,1.50),
(12, 'Egypt' ,20 , 1.60),
(13, 'Sri Lanka' ,94 , 1.70)
Обратите внимание, что если вы хотите сделать количество строк, которые вы извлекаете при каждом вызове одного из параметров хранимой процедуры, то вам придется динамически генерировать SQL - запрос в теле SP-в этой статье объясняется, как это сделать.
Построение динамического SQL в хранимой процедуре[
^]