Tom>SET @MaxRecord = cast((@Page * @PageSize + @PageSize) as varchar(10))
Tom>SET @Count = cast(@PageSize as varchar(10))
Tom>EXECUTE ('SELECT * FROM
Tom> (SELECT TOP ' + @Count + ' * FROM
Tom> (SELECT TOP ' + @MaxRecord + ' * FROM sysobjects
Tom> ORDER BY name ASC) SO1
Tom> ORDER BY name DESC) SO2
Tom> ORDER BY name')
Tom>В данном коде есть баг (фича? ). Если номер страницы указать больше, чем есть данных, то возвращается всё равно последняя страница, а не пустая выборка. Это не очень удобно, когда paging делается без предварительной выборки кол-ва записей, а используя возвращённое кол-во записей.
Да нет здесь ни бага ни фичи — топ так и должен работать. Топ означет "не больше чем". Такой метод постраничной выборки приводит к тому, что с увеличением номера страницы увеличивается промежуточный результирущий набор, а это не есть гуд.
Я бы реализовал постраничную выборку по другому: отказался от номеров страниц, а опорной точкой служило бы последнее значение уникального ключа (здесь — name), выбранного со страницы. Или же первое значение ключа, если двигаемся назад.
Выборка следующей страницы выглядела бы так (псевдокод):
select top @PageSize
*
from
sysobjects as so
where
so.name > [последнее значение name на тек. странице]
order by
so.name
Выборка предыдущей:
select
*
from
(select top @PageSize
*
from
sysobjects as so
where
so.name < [первое значение name на тек. странице]
order by
so.name desc
) as Page
order by
Page.name
ИБ>Авторы: ИБ> Иван Бодягин
ИБ>Аннотация: ИБ>Уникальная идентификация записей в таблице, является практически основой реляционных СУБД. Вообще в реляционной теории предполагается, что если две записи ни чем друг от друга не отличаются, то это явная избыточность, и количество таких записей можно сократить до одной. Собственно вопросам этой самой идентификации, каковых возникает на удивление много, и посвящен этот FAQ.
You wrote>>Ключевое слово IDENTITY может быть указано при создании CREATE TABLE, или изменении таблицы ALTER TABLE
Вот понадобилось всавить Identity после создания таблицы... и без промежуточного удаления и нового создания таблицы...ТО есть используя Alter Table...А как – не знаю... Может кто знает . возможно жто вообще или в статье ошибка? Если возможно...помогите примером типа :
ALTER TABLE SET Ident_table (ID int IDENTITY(1, 1), some_values varchar(50))...
Здравствуйте, altmenn, Вы писали: A>You wrote>>Ключевое слово IDENTITY может быть указано при создании CREATE TABLE, или изменении таблицы ALTER TABLE
A>Вот понадобилось всавить Identity после создания таблицы... и без промежуточного удаления и нового создания таблицы...ТО есть используя Alter Table...А как – не знаю...
Ну так надо же все-таки в доки иногда глядеть.
Еолонка identity добавляется в существующую таблицу следующим образом:
alter table <table_name> add <column_name> int identity
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, altmenn, Вы писали: A>>You wrote>>Ключевое слово IDENTITY может быть указано при создании CREATE TABLE, или изменении таблицы ALTER TABLE
A>>Вот понадобилось всавить Identity после создания таблицы... и без промежуточного удаления и нового создания таблицы...ТО есть используя Alter Table...А как – не знаю... S>Ну так надо же все-таки в доки иногда глядеть. S>Еолонка identity добавляется в существующую таблицу следующим образом: S>
S>alter table <table_name> add <column_name> int identity
S>
Здравствуйте, altmenn, Вы писали:
A>вот и я о том же...
Дык так и надо спрашивать...
A>А в Enterprise Manager — всеrо один ComboBox...
EM, по этому комбобоксу, создает временную таблицу, выгружает в нее данные из столбца, грохает столбец, создает такой же но identity, выставляет SET IDENTITY_INSERT в ON, заливает данные из временной таблицы обратно и, наконец, ставит IDENTITY_INSERT в OFF.
Вообще в EM есть нарошная кнопка, по которой можно получить непосредственно скрипт, который выполняет EM для своих манипуляций, ну или профайлером можно отследить... Очень полезная штука для самообразования.
Здравствуйте, Иван Бодягин, Вы писали:
...
В последнем примере:
SELECT * FROM
(SELECT TOP (@PageSize) * FROM
(SELECT TOP (@Page * @PageSize + @PageSize) * FROM sys.objects
ORDER BY name ASC) SO1
ORDER BY name DESC) SO2
ORDER BY name
при числе записей не кратном @PageSize на ПОСЛЕДНЮЮ страницу попадают последние @PageSize записей.
Т.е. если, допустим, всего 16 записей, а @PageSize=15, то
для Page N0 даипазон rowIndex=[0..14] , и
для Page N1 даипазон rowIndex=[1..15].
В моем случае номер записи, который я показываю пользователю, выводится как @Page * @PageSize+Индекс_записи_на_странице, т.е.
для приведенного примера запись с rowIndex=3 на нулевой странице отобразится как третья, а на последней, как 15+2=16.
Таким образом, уникальность индекса нарушается
Возможно это не баг, а фича. Или я неправильно вычисляю индекс для отображения пользователю, но в любом случае, стоит явно упомянуть о такой особенности работы запроса.
Здравствуйте, Grenal, Вы писали:
G>В последнем примере:
Для MSSQL 2005 пэйджинг вообще лучше всего делать так:
WITH Numbered (
SELECT ROW_NUMBER() OVER(ORDER BY <стобец для сортировки>) N_Row, * FROM <таблица для пейджинга> )
SELECT * FROM Numbered WHERE N_Row between <начальная запись> AND <конечная запись>
Здравствуйте, Иван Бодягин, Вы писали: ИБ>Текущее значение счетчика в базе данных хранится в переменной @@DBTS.
Тем не менее, получать значение при добавлении/изменении записи с помощью переменной @@DBTS не рекомендуется в виду той же проблемы с identity, когда мы используем SCOP_IDENTITY вместо @@IDENTITY. Для timestamp отсутствует аналог SCOP_IDENTITY, поэтому, во избежании проблем, приходится делать select timestampField from tbl where ID=@ID.
В MSSQL2005 поэффективнее — можно использовать OUTPUT INSERTED.timeStampField.
Также не рассмотрен вопрос о реализации сквозной нумерации в отсоединенных приложениях.
Я имею ввиду решения на основе пула идетификаторов, их захвата и возвращения неиспользованных обратно в пул.
Здравствуйте, снежок, Вы писали:
С>Также не рассмотрен вопрос о реализации сквозной нумерации в отсоединенных приложениях. С>Я имею ввиду решения на основе пула идетификаторов, их захвата и возвращения неиспользованных обратно в пул.
Я что-то сегодня непонятливый какой-то. Где и кем не рассмотрен?
С>>Также не рассмотрен вопрос о реализации сквозной нумерации в отсоединенных приложениях. С>>Я имею ввиду решения на основе пула идетификаторов, их захвата и возвращения неиспользованных обратно в пул. ___>Я что-то сегодня непонятливый какой-то. Где и кем не рассмотрен?
Автором в статье
Здравствуйте, снежок, Вы писали:
С>Также не рассмотрен вопрос о реализации сквозной нумерации в отсоединенных приложениях. С>Я имею ввиду решения на основе пула идетификаторов, их захвата и возвращения неиспользованных обратно в пул.
Ну так рассмотри, в чем проблема?