powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Как сделать интеллектуальное IDENTITY
12 сообщений из 12, страница 1 из 1
Как сделать интеллектуальное IDENTITY
    #32007297
skif
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Проблема такая. Есть табличка, в которой есть поле типа ключа, пусть будет ID. Если заносится новая запись, то в поле ID заносится новое максимальное значение. Но простое IDENTITY не проходит, так как проблема такая. Если я потом удаляю, к промеру, запись с ID = 5, к примеру, то при следующем добавлении я должен проверить, есть ли "сквозняки" в номерах ID и использовать именно эти "выпавшие" номера. Похоже, это работа под тригер, но я совсем совсем poor SQL.
...
Рейтинг: 0 / 0
Как сделать интеллектуальное IDENTITY
    #32007300
Andr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще вешать триггер, который будет менять ключевое поле крайне неразумно, особенно, если клиент дельфовый и запись производится по принципу TDataSet.Post. При этом возникает ошибка EDBEngineError (Another user has changed current record).
Эту проблему лучше решать с помощью Stored procedure, запихивая в качестве аргумента, соответствующего этому ключевому полю, некую бредятину, например -1, а в теле процедуры вычислять нужное значение и возвращать его клиенту в виде OUTPUT параметра.
...
Рейтинг: 0 / 0
Как сделать интеллектуальное IDENTITY
    #32007301
Павел
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ключ = это только ключ, и ничего больше. Так что на мой взгляд самое правильное - пересмотреть свой поход к структуре данных.
...
Рейтинг: 0 / 0
Как сделать интеллектуальное IDENTITY
    #32007303
skif
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Пусть будет не ключ - нет проблем. Грубо говоря, поле. Просто поле типа INT. Delphi абсолютно не при чем. Работа из VB + C++ через ADO, потому и нужно все впихнуть внутрь базы - нельзя это делать за счет программной логики. И какой-то идеи на счет алгоритма поиска "дырки" нет. Кажется, надо сначала разбить значения ключа на сотни, к примеру, и посмотреть, если в диапазоне от 101 до 200 есть сто строк, то здесь дырки нет. А если в этом диапазоне есть дырка, то записей будет меньше, и тогда что? Переходить по одной от 101 и до..., запоминая предыдущее значение? Никаких идей нет? Скорее всего, кто-то реализовывал подобное, может, кто ссылку даст? И еще - UDF нельзя, SQL 7.0.

Благодарен за любые намеки.
...
Рейтинг: 0 / 0
Как сделать интеллектуальное IDENTITY
    #32007305
bitof
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
вообщем вижу такой путь:
допустим имя твоей таблицы TBL:

1. Содаешь вспомогательную таблицу, которая будет генерить уникальные ID-шники для ключа (IDSource)
2. Создаешь еще одну таблицу в которой будушь хранить ключи для удаленных записей. (IDDeleted)
3. Создаешь триггкр на удаление из исходной таблицы, который будет копировать удаленные ID-шники в IDDeleted
4. Insert в TBL делаешь через продцедуру. В ней сначала проверяешь есть ли что нибудь в IDDeleted. Если есть берешь ID-шник оттуда, после чего удаляешь соотв. запись, если нет берешь из IDSource.
...
Рейтинг: 0 / 0
Как сделать интеллектуальное IDENTITY
    #32007306
bitof
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
примерно такой код:

create table IDSource (ID int IDENTITY, Desc char(3))

create table IDDeleted (ID int)

create trigger TR_DELonTBL on TBL for DELETE
as
insert into IDDeleted select ID from deleted

create proc INSintoTBL
as
declare @ID int
if exists (select ID from IDDeleted)
begin
select @ID=ID from IDDeleted where ID in (select min(ID) from IDDeleted)
delete from IDDeleted where ID=@ID
insert into TBL (ID, ...) values (@ID, ....)
end
else
begin
insert into IDSource select 'bla'
insert into TBL (ID, ...) values (@@IDENTITY,....)
end
...
Рейтинг: 0 / 0
Как сделать интеллектуальное IDENTITY
    #32007315
Zack
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SELECT TOP 1 * FROM Your_Table WHERE Your_Column IS NULL вернет первую запись с дыркой.
...
Рейтинг: 0 / 0
Как сделать интеллектуальное IDENTITY
    #32007319
Kapik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если, например, используется таблица Products, то так:

DECLARE @minidentval int
DECLARE @nextidentval int

SET IDENTITY_INSERT Products ON

SELECT @minidentval = MIN(IDENTITYCOL) FROM Products
IF @minidentval = IDENT_SEED('Products')
SELECT @nextidentval = MIN(IDENTITYCOL) + IDENT_INCR('Products')
FROM Products o
WHERE IDENTITYCOL BETWEEN IDENT_SEED('Products') AND 2147483647 AND
NOT EXISTS (SELECT * FROM Products oo
WHERE oo.IDENTITYCOL = o.IDENTITYCOL +
IDENT_INCR('Products'))
ELSE
SELECT @nextidentval = IDENT_SEED('Products')
set @ProdId = @nextidentval

...

insert

...

SET IDENTITY_INSERT Products OFF
...
Рейтинг: 0 / 0
Как сделать интеллектуальное IDENTITY
    #32007332
Fompro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В SP приблизительно так:
IF NOT EXISTS(SELECT Doc_No FROM Docs)
SELECT @Doc_No=1
ELSE
SELECT @Doc_No=MIN(D.Doc_No) + 1 FROM Docs D WHERE NOT EXISTS(SELECT * FROM Docs D2 WHERE D2.Doc_No=D.Doc_No + 1)
Собственно говоря, в этой таблице есть свой PK и он - IDENTITY, но вот номера документов должны идти "сплошняком".
...
Рейтинг: 0 / 0
Как сделать интеллектуальное IDENTITY
    #32007403
Alexander Rudenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
--Есть такой вариант:
--- создаем временную таблицу, в которой будут все номера подряд (или храним эту таблицу в базе)
DECLARE @count int
SET @count = 1
CREATE TABLE #tmp (code int)
WHILE @count<190
BEGIN
INSERT INTO #tmp (code) VALUES (@count)
SET @count = @count + 1
END
--Затем получаем все свободные номера и берем какой нужно.
SELECT code FROM #tmp
WHERE #tmp.code NOT IN (SELECT code_category FROM category)
ORDER BY code
...
Рейтинг: 0 / 0
Как сделать интеллектуальное IDENTITY
    #32007449
zamm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Немного модифицирую запрос приведенный выше (от Fompro), мне кажется так немного быстрее.

SELECT top1 D.Doc_No + 1 FROM Docs D WHERE NOT EXISTS(SELECT * FROM Docs D2 WHERE D2.Doc_No=D.Doc_No + 1)
...
Рейтинг: 0 / 0
Как сделать интеллектуальное IDENTITY
    #32007454
Fompro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Скрипт был от 6.5
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Как сделать интеллектуальное IDENTITY
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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