Исправления порядкового номера в таблице

Работа VB и СУБД (Access, MSSQL, MySQL, Oracle и пр.)
Правила форума
При создании новой темы не забывайте указывать используемую СУБД.
Roman Koff
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 495
Зарегистрирован: 17.09.2008 (Ср) 9:22
Откуда: От туда

Исправления порядкового номера в таблице

Сообщение Roman Koff » 16.04.2009 (Чт) 11:09

Имеется таблица с данными.
В таблице определено поле Ord int содержащее порядковый номер строк таблицы.
По этому полю производится сортировка данных перед выводом в редакторе.
Соответственно имеется некий механизм позволяющий менять номер строки таблицы для повышения или понижения ее позиции (обмен значений между соседними строками)
Для избежания возможных коллизий хоцца сделать принудительную фиксацию этого поля перед запросом на редактирование

Код создания таблицы:
Код: Выделить всё
CREATE TABLE Lists(
   Id int IDENTITY (1, 1) PRIMARY KEY,
   Ord int DEFAULT 0,
   Login varchar(50) NOT NULL,
   Data varchar(500) NOT NULL,
) ON [PRIMARY]
GO


Код процедуры получения списка для редактирования:
Код: Выделить всё
CREATE PROCEDURE List_Select () AS
   .........
   SELECT * FROM dbo.Lists
   ORDER BY Ord
GO


Подскажите, пожалуйста, каким образом можно заново прописать для таблицы поля Ord в значения от 0 до [count]-1 при сортировке по текущим значениям Ord
Слава роботам! Убить всех человеков! Bite my shiny metal ass!

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: Исправления порядкового номера в таблице

Сообщение alibek » 16.04.2009 (Чт) 12:23

Если база MSSQL, то через IDENTITY.
Можно создать виртуальную таблицу с полями id и ord; id берется из основной таблицы, ord будет identity.
Можно курсором ее пробежать, тогда даже identity не нужен.

Но мне непонятно, зачем нужно перенумеровывать строки. Если две строки переставляются местами, то изменения нужно применить только к этим двум строкам. Если индекс по полю Ord не требует уникальности, то это два update, если требует, то три.
Lasciate ogni speranza, voi ch'entrate.

Roman Koff
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 495
Зарегистрирован: 17.09.2008 (Ср) 9:22
Откуда: От туда

Re: Исправления порядкового номера в таблице

Сообщение Roman Koff » 16.04.2009 (Чт) 14:52

Для таблицы не обеспечивается целостность данных и могут возникнуть коллизии с повторяющимися порядковыми номерами или пропусками.
От этого надо уйти.

Я с курсорами не работал никогда, в каком направлении копать?

А что будет эффективнее - курсоры или временная таблица?
Слава роботам! Убить всех человеков! Bite my shiny metal ass!

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: Исправления порядкового номера в таблице

Сообщение alibek » 16.04.2009 (Чт) 15:55

Временная таблица. Почти все ДБА не любят курсоры и, обычно, обосновано. Курсоры оптимальны для довольно малого количества задач.
Lasciate ogni speranza, voi ch'entrate.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: Исправления порядкового номера в таблице

Сообщение alibek » 16.04.2009 (Чт) 15:56

Roman Koff писал(а):Для таблицы не обеспечивается целостность данных и могут возникнуть коллизии с повторяющимися порядковыми номерами или пропусками.

Например?
Lasciate ogni speranza, voi ch'entrate.

Roman Koff
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 495
Зарегистрирован: 17.09.2008 (Ср) 9:22
Откуда: От туда

Re: Исправления порядкового номера в таблице

Сообщение Roman Koff » 16.04.2009 (Чт) 16:04

С курсорами я наваял такой вариант, вроде работает, все ли верно?

Код: Выделить всё
DECLARE @Ord INT SET @Ord = 0
DECLARE @Status INT
DECLARE @Ord2 INT
DECLARE CURS1 CURSOR FOR SELECT Ord FROM dbo.Lists ORDER BY Ord
OPEN CURS1 SELECT @Status = 0
WHILE @Status = 0 BEGIN
   FETCH CURS1 INTO @Ord2 SELECT @Status = @@FETCH_STATUS
   IF @Status = 0 BEGIN
      UPDATE dbo.Lists SET Ord = @Ord WHERE CURRENT OF CURS1
   END
   SET @Ord = @Ord + 1
END
CLOSE CURS1
DEALLOCATE CURS1
Последний раз редактировалось Roman Koff 16.04.2009 (Чт) 16:10, всего редактировалось 1 раз.
Слава роботам! Убить всех человеков! Bite my shiny metal ass!

Roman Koff
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 495
Зарегистрирован: 17.09.2008 (Ср) 9:22
Откуда: От туда

Re: Исправления порядкового номера в таблице

Сообщение Roman Koff » 16.04.2009 (Чт) 16:07

Коллизии могут возникнуть при удалении строки таблицы, кроме того таблица реализует дерево подчиненных объектов, при перемещении веток по горизонтали номера соседей будут одинкаовыми. Так и так прийдется делать пересортировку
Слава роботам! Убить всех человеков! Bite my shiny metal ass!

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: Исправления порядкового номера в таблице

Сообщение alibek » 16.04.2009 (Чт) 16:29

Все-равно не понятно, отчего могут возникнуть коллизии.
Выполняешь delete from ... where ord=5, затем update ... set ord=ord-1 where ord>5.
Заключаешь код в begin tran ... commit tran и никаких коллизий быть не должно.

Советую все-же обойтись без курсора. На больших таблицах разница в скорости будет чуть ли не на порядок.
Lasciate ogni speranza, voi ch'entrate.

Roman Koff
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 495
Зарегистрирован: 17.09.2008 (Ср) 9:22
Откуда: От туда

Re: Исправления порядкового номера в таблице

Сообщение Roman Koff » 16.04.2009 (Чт) 16:52

Разумное зерно. Возьму на вооружение, спасибо ...
Слава роботам! Убить всех человеков! Bite my shiny metal ass!


Вернуться в Базы данных

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 109

    TopList