Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Удаление поля c autoincrement / 15 сообщений из 15, страница 1 из 1
26.09.2002, 16:54:00
    #32053398
Larvef
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление поля c autoincrement
Заранее прошу прощения за возможно глупый вопрос. Но я так и не понял, что делать при удалении строки с полем, скажем, id identity(1,1), чтобы его unique id освобождался и следующая запись принимала этот id, а не на единицу больше?
...
Рейтинг: 0 / 0
26.09.2002, 17:15:22
    #32053407
akuz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление поля c autoincrement
Код: plaintext
1.
2.
declare @id int
set @id = isnull((select max(id) from table), 1 )
dbcc checkident (table, reseed, @id)
...
Рейтинг: 0 / 0
26.09.2002, 17:19:30
    #32053411
Makc
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление поля c autoincrement
Токо на триггер Delete повесьте
...
Рейтинг: 0 / 0
27.09.2002, 09:56:20
    #32053533
Larvef
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление поля c autoincrement
Спасибо!
...
Рейтинг: 0 / 0
27.09.2002, 11:07:48
    #32053563
Jimmy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление поля c autoincrement
2 akuz

Это сработает только для случая, если удаляются последние записи (с наивысшим ID).
Иначе - остаются дыры в последовательности:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
create table inctest (id int identity( 1 , 1 ), name char( 10 ))
go
declare @i int
set @i= 100 
while @i >  0  begin
    insert inctest (name) values( 'line ' + cast(@i as char( 3 )) )
    set @i = @i -  1 
end
go
delete inctest where id between  5  and  95 
go
delete inctest where id >  98 
go
declare @id int
set @id = isnull((select max(id) from inctest), 1 )
dbcc checkident (inctest, reseed, @id)
go
insert inctest (name) values( 'new line 1')
insert inctest (name) values( 'new line 2')
insert inctest (name) values( 'new line 3')
go
select * from inctest order by  1 
go

 --- results ---
 
id          name       
 ----------- ---------- 
 
 1 . 00         line  100   
 2 . 00         line  99    
 3 . 00         line  98    
 4 . 00         line  97    
 96 . 00        line  5     
 97 . 00        line  4     
 98 . 00        line  3     
 99 . 00        new line  1 
 100 . 00       new line  2 
 101 . 00       new line  3 

( 10  row(s) affected)


ЗЫ Конечно, все зависит от того, что же всетаки подразумевалось под этим: " Но я так и не понял, что делать при удалении строки с полем, скажем, id identity(1,1), чтобы его unique id освобождался и следующая запись принимала этот id, а не на единицу больше? "
...
Рейтинг: 0 / 0
27.09.2002, 11:16:20
    #32053568
dao
dao
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление поля c autoincrement
Пмсать свой механизим вычесления id -мне по этому поводу ничего другого придумать не удалось (правда решал эту задачу на оракле - да не забьют меня камнями :)) )
...
Рейтинг: 0 / 0
27.09.2002, 13:01:06
    #32053638
akuz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление поля c autoincrement
2 Jimmy
остаются дыры в последовательности
Автоинкремент на то и автоинкремент, чтобы лишь наращивать значения ключа, а не поддержиать последовательность без дыр.
Для поддержания такой последовательности надо использовать первичный ключ без инкремента и при вставке записи вычислять первую не заполненную дырку. Беда в том, что при этом без курсора не обойтись :(
Да в общем то и смысла особого дырки заполнять не вижу.

А если, например в процессе разработки или тестирования на рабочей системе вы чего-то в таблицы временно заносите, а затем удаляете, то dbcc checkident как раз и помогает в данной ситуации.
...
Рейтинг: 0 / 0
27.09.2002, 13:10:57
    #32053648
dao
dao
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление поля c autoincrement
2 akuz - задача была такая Есть набор "документов" и их нумерация не должна содержать пробелов соответственно номер есть признак а не pk - так еще осложнялосьтем что вводиться документы могли с разных компов - и для каждого места определялся свой механизм нумерации документов а в итоге по всем документам не должно быть пропусков
...
Рейтинг: 0 / 0
27.09.2002, 13:53:14
    #32053668
Jimmy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление поля c autoincrement
2 akuz
Можно и без курсора обойтись для вычисления начала "дыры". Для моего скрипта (см. выше):

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
 -- посмотрим, что есть в таблице
 
select * from inctest
go

 --- results ---
 
id          name       
 ----------- ---------- 
 
 1 . 00         line  100   
 2 . 00         line  99    
 3 . 00         line  98    
 4 . 00         line  97    
 99 . 00        new line  1 
 100 . 00       new line  2 
 101 . 00       new line  3 
 96 . 00        line  5     
 97 . 00        line  4     
 98 . 00        line  3     

( 10  row(s) affected)

 -- выберем существующий ID перед дырой
 
select min(id) as id from inctest
where id not in(select id- 1  from inctest)
go

 --- results ---
 
id            
 ----------- 
 
 4 . 00 

( 1  row(s) affected)


2 Larvef
Только тепрь нужно будет проверять, дыра ли это или запрос вернул последнее значение ID.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
 -- если дыра
 
set identity_insert inctest on
insert inctest(id,name) values( 5 ,'заполнили')
set identity_insert inctest off

 -- иначе
 
insert inctest(name) values('добавили')
...
Рейтинг: 0 / 0
27.09.2002, 14:36:40
    #32053691
akuz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление поля c autoincrement
2 Jimmy
А теперь попробуйте написать операцию вставки значений из другой таблицы с кол-вом строк > 1 без использования триггера.
типа:
Код: plaintext
1.
2.
insert inctest (name)
select top  2  name
from inctest2
...
Рейтинг: 0 / 0
27.09.2002, 14:44:42
    #32053697
Jimmy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление поля c autoincrement
2 akuz
Так я о триггерах ничего и не говорил в данном трэде :0))
И вообще не обсуждал целесообразность такой гибридной систему нумерации, т.к. изначально понятно, что будут капканы, напрмер возможные конфликты номеров при интенсивных вставках и наличии дыр.
...
Рейтинг: 0 / 0
27.09.2002, 15:18:09
    #32053718
akuz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление поля c autoincrement
2 Jimmy
Сори, обшибся, я имел ввиду курсор , конечно, а не триггер.

А конфликты-то как раз можно уладить блокировкой ключа в транзакции.
...
Рейтинг: 0 / 0
27.09.2002, 17:04:08
    #32053781
Genady
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление поля c autoincrement
Позволю себе поинтересоваться, а нафига козе баян, в смысле нафига дыры латать?
Ну кто нибудь может привести пример из жизни, когда это действительно нужно?
...
Рейтинг: 0 / 0
27.09.2002, 17:06:50
    #32053783
dao
dao
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление поля c autoincrement
2 Genady смотри мой топик выше -пример из жизни :))
...
Рейтинг: 0 / 0
27.09.2002, 17:13:38
    #32053785
Genady
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Удаление поля c autoincrement
2 dao
смотри мой топик выше -пример из жизни :))

Выше чего? А ну да, понятно, не царское это дыло ссылки давать.
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Удаление поля c autoincrement / 15 сообщений из 15, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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