Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Детский вопрос: перенумерация уникального поля / 13 сообщений из 13, страница 1 из 1
15.07.2009, 14:35
    #36091282
user233
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Детский вопрос: перенумерация уникального поля
ASE 15

В таблице есть поле типа numeric
в нём номера записей (не identity), просто по порядку 1,2,3,...,N
по этому полю создан уникальный индекс

Есть потребность перенумеровать часть таблицы начиная с определённой записи на +1

Вопрос:
Можно ли это сделать простым запросом или придётся писать процедуру, которая будет перенумеровывать сверху вниз, чтобы индекс не ругался на duplicate key?
...
Рейтинг: 0 / 0
15.07.2009, 16:30
    #36091621
Mikle83
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Детский вопрос: перенумерация уникального поля
Update Table
Set ID = ID + 1
where ID between MinID and MaxID

при этом если у вас нет записи с идентификатором ID = MaxID + 1
то все сработает без проблем
...
Рейтинг: 0 / 0
15.07.2009, 17:36
    #36091830
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Детский вопрос: перенумерация уникального поля
создаем тестовые данные:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
create table #t(id integer primary key, c char( 1 ) null)
go
insert into #t
select  1 , 'a' union
select  2 , 'b' union
select  3 , 'c' union
select  4 , 'd' union
select  5 , 'e' union
select  6 , 'f' union
select  7 , 'g' union
select  8 , 'h' union
select  9 , 'i' union
select  10 , 'j' union
select  11 , 'k'
go
Пробуем раз:
Код: plaintext
Update #t Set id = id +  1  where id between  4  and  7 
получаем:
Код: plaintext
1.
Attempt to insert duplicate key row in object '#t00001260010234421' with unique index '_t_id_16105276581'
Command has been aborted.

Пробуем два:
Код: plaintext
Update #t Set id = id +  1  where id between  7  and  11 
получаем:
Код: plaintext
(5 rows affected)

проверяем:
Код: plaintext
select * from #t
idc1a2b3c4d5e6f8g9h10i11j12k
Долго думаем....
...
Рейтинг: 0 / 0
15.07.2009, 20:39
    #36092139
Ex_Soft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Детский вопрос: перенумерация уникального поля
/me думает: в далекие-далекие времена...
_________________
"Helo, word!" - 17 errors 56 warnings
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
16.07.2009, 08:34
    #36092436
User233
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Детский вопрос: перенумерация уникального поля
Запросы типа:
Код: plaintext
1.
2.
3.
Update Table
Set ID = ID +  1 
where ID between MinID and MaxID
Код: plaintext
Update #t Set id = id +  1  where id between  7  and  11 
Вызывают:
Attempt to insert duplicate key row in object ...

Возможно на 5 записях и работают, но у меня тут большая таблица, особые настройки сервера, множество других индексов.
В Update же нельзя сказать order by ... desc

Сделал такой скрипт:
Код: plaintext
1.
2.
3.
4.
5.
6.
declare @ID numeric( 10 )
select @ID = max(ID) from Table
while @ID >  4000 
begin
  update Table set ID = ID +  1  where ID = @ID
  select @ID = max(ID) from Table where ID < @ID
end
Работает.
Мне просто интересно, можно ли это же сделать одним красивым запросом?
...
Рейтинг: 0 / 0
16.07.2009, 08:59
    #36092456
User233
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Детский вопрос: перенумерация уникального поля
У меня уникальный индекс вовсе не "primary key" и даже не кластерный.
Это один из индексов, к тому же сразу по трём полям, одно из которых то самое что надо изменить.
Поля типа identity в этой таблице вообще нет, как и кластерного индекса.
...
Рейтинг: 0 / 0
16.07.2009, 09:41
    #36092520
Ex_Soft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Детский вопрос: перенумерация уникального поля
User233
У меня уникальный индекс вовсе не "primary key"...

Вообще-то подразумевался алгоритм:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
update
   Table
set
   Id=Id*- 1 
where
   Id between MinID and MaxID

update
   Table
set
   Id=Id*- 1 + 1 
where
   Id between -MaxID and -MinID
_________________
"Helo, word!" - 17 errors 56 warnings
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
16.07.2009, 11:19
    #36092803
Mikle83
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Детский вопрос: перенумерация уникального поля
User233Запросы типа:
Код: plaintext
1.
2.
3.
Update Table
Set ID = ID +  1 
where ID between MinID and MaxID
Код: plaintext
Update #t Set id = id +  1  where id between  7  and  11 
Вызывают:
Attempt to insert duplicate key row in object ...


Хм... Вроде русским по черному написано было:
"при этом если у вас нет записи с идентификатором ID = MaxID + 1
то все сработает без проблем"


Как изначально Вами предполагается разруливание этой ситуации?
Если вы хотите апдейтить записи с ИД 1,2,3,4 а в таблице уже есть запись с ИД = 5?
Старый идентификатор 4 должен превратиться в 5, что само собой потянет за собой
"Attempt to insert duplicate key row in object ..."
Что должно стать со старой записью, у которой ИД = 5?

Если же вы апдейтите последовательность идентификаторов N,N+1,...., N+K
и в таблице нет идентификатора N+K+1 то все сработает без проблем.


declare @ID numeric(10)
select @ID = max(ID) from Table
while @ID > 4000
begin
update Table set ID = ID + 1 where ID = @ID
select @ID = max(ID) from Table where ID < @ID
end


Извините, но этот запрос у вас отработает только в случае, если изначально есть в таблице ID > 4000... В противном случае у вас просто ни разу в условие не зайдет...

Во вторых, он обновляет только те записи, которые имеют идентификатор более 4000... Но на асе с этим успешно справляется запрос

Update Table set ID = ID + 1 where ID > 4000

и не выдает никаких эксепшенов при этом
по крайней мере на
'Adaptive Server Enterprise/15.0.2/EBF 14332/P/NT (IX86)/Windows 2000/ase1502/2486/32-bit/OPT/Thu May 24 04:10:36 2007'
...
Рейтинг: 0 / 0
16.07.2009, 12:43
    #36093084
user233
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Детский вопрос: перенумерация уникального поля
Mikle83Хм... Вроде русским по черному написано было:
"при этом если у вас нет записи с идентификатором ID = MaxID + 1
то все сработает без проблем"

Не поверите, нет записей с ID = MaxID + 1

Mikle83Как изначально Вами предполагается разруливание этой ситуации?
Если вы хотите апдейтить записи с ИД 1,2,3,4 а в таблице уже есть запись с ИД = 5?
Старый идентификатор 4 должен превратиться в 5, что само собой потянет за собой
"Attempt to insert duplicate key row in object ..."
Что должно стать со старой записью, у которой ИД = 5?
С ИД = 5 записей нет, нужно проапдейтить начиная с ИД = 2 и до конца, т.е. до ИД = 4
должно получиться 1,2,4,5

Mikle83Если же вы апдейтите последовательность идентификаторов N,N+1,...., N+K
и в таблице нет идентификатора N+K+1 то все сработает без проблем.
Я апдейчу с определённого ИД и до конца

Mikle83 declare @ID numeric(10)
select @ID = max(ID) from Table
while @ID > 4000
begin
update Table set ID = ID + 1 where ID = @ID
select @ID = max(ID) from Table where ID < @ID
end


Извините, но этот запрос у вас отработает только в случае, если изначально есть в таблице ID > 4000... В противном случае у вас просто ни разу в условие не зайдет...

Во вторых, он обновляет только те записи, которые имеют идентификатор более 4000... Но на асе с этим успешно справляется запрос

Update Table set ID = ID + 1 where ID > 4000

и не выдает никаких эксепшенов при этом
по крайней мере на
'Adaptive Server Enterprise/15.0.2/EBF 14332/P/NT (IX86)/Windows 2000/ase1502/2486/32-bit/OPT/Thu May 24 04:10:36 2007'
Конечно у меня в таблице есть ID > 4000. Я же писал в первом сообщении "Есть потребность перенумеровать часть таблицы начиная с определённой записи на +1"
Запрос подобный вашему простому апдейту не справляется, выдаёт "Attempt to insert duplicate key..."
У вас работает возможно из-за наличия индекса primary key, а у меня этот уникальный индекс далеко не первый и не единственный на таблице (уникальный только один), и нет ни кластерного ни идентити и сервер выбирает записи для апдейта в любом удобном ему порядке.
Допустим мне надо перенумеровать 500 записей из 1000, от 500 и до конца, до 1000, чтобы из 1,2,...,500,501,502,...,1000, получилось 1,2,...,500,502,503,...,1001
Вашим запросом сервер начинает апдейтить как ему вздумается, допустим по возрастанию:
501 = 501 + 1
что уже приводит к конфликту, т.к. запись 502 уже была.
Надо чтобы он пошел апдейтить так:
1000 = 1000 + 1
999 = 999 + 1
...
Именно это делает мой скрипт, только по одной записи за раз.

Мне было просто интересно, из чистого любопытства, можно ли эту операцию проделать одиночным запросом без ошибок duplicate key.
...
Рейтинг: 0 / 0
16.07.2009, 12:58
    #36093156
Ex_Soft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Детский вопрос: перенумерация уникального поля
[quote user233
сервер начинает апдейтить как ему вздумается, допустим по возрастанию:
501 = 501 + 1
что уже приводит к конфликту, т.к. запись 502 уже была.
[/quote]
/me думает: таки дежавю... Так Вас чем не устраивает?
_________________
"Helo, word!" - 17 errors 56 warnings
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
16.07.2009, 13:58
    #36093411
user233
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Детский вопрос: перенумерация уникального поля
Ex_Soft
user233
сервер начинает апдейтить как ему вздумается, допустим по возрастанию:
501 = 501 + 1
что уже приводит к конфликту, т.к. запись 502 уже была.

/me думает: таки дежавю... Так Вас чем не устраивает?


Нормально, работает. :)
...
Рейтинг: 0 / 0
17.07.2009, 06:17
    #36094624
golsa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Детский вопрос: перенумерация уникального поля
Можно сделать так:

Drop index ...

Update ...
set ID =

Create index ...
...
Рейтинг: 0 / 0
17.07.2009, 07:14
    #36094648
user233
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Детский вопрос: перенумерация уникального поля
golsaМожно сделать так:

Drop index ...

Update ...
set ID =

Create index ...
Долго ждать, однако.
Пока этот индекс создастся... на большой таблице и рабочей базе, к тому же кому-то этот индекс нужен, т.к. пользователи работают.
...
Рейтинг: 0 / 0
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Детский вопрос: перенумерация уникального поля / 13 сообщений из 13, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]