Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

ID последней добавленной записи [D7, любая СУБД]


Страницы:   1 2 3 4 5

DVM ©   (2008-09-04 12:03:00) 

Вопрос тут уже вроде всплывал тут, но в основном касался каких то конкретных СУБД, например Access. Мне же нужен по возможности универсальный вариант, ну пусть хотя бы одинаково работающий в Access, MySQL, MSSQL, Oracle.

Посредством SQL запроса в таблицу добавляется некая запись. Одним из полей таблицы является автоинкрементное поле счетчик (ID).
После добавления записи в таблицу мне нужно получить значение поля ID для этой добавленной записи.

Как в таких случаях обычно поступают? Писать разный код для разных СУБД? Ввести свое доп. поле в которое пихать собственноручно сгенерированное чудо типа GUID и сразу после добавления находить запись по этому полю?


Кщд   (2009-03-11 14:52:00) [21]

>oleg_at   (11.03.09 14:01) [64]
>В стандарте SQL определены четыре уровня изоляции: READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ и SERIALIZABLE.
это всё просто великолепно
но Вы уверены, что каждая из перечисленных у топикстартера СУБД поддерживает все эти уровни?
и уверены ли Вы, что эти уровни в указанных СУБД соответствуют стандарту ANSI на 100%?)


Sergey13   (2009-03-11 14:31:00) [22]

> [64] oleg_at   (11.03.09 14:01)

Ну дал Бог! Пришел мессия! Всего то полгода ждали.
8-)


oleg_at   (2009-03-11 14:01:00) [23]

Уважаемый Правильный$Вася!
Вы теоретик или практик?
Во первых чтоб рассуждать о транзакциях, нужно уточнить - какой уровень?
Во-вторых, есть такое
mysql_insert_id
mysql_insert_id -- Получает id сгенерированный предыдущим выполнением sql-запроса insert
И в третьих, все ваши, а вдруг похожи на,
"А кто пробовол съесть слона"!
P.S. читайте Маркса:
В стандарте SQL определены четыре уровня изоляции: READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ и SERIALIZABLE. Они перечислены в порядке увеличения изолированности и по очереди решают три основные проблемы, возникающие при использовании транзакций: появление промежуточных данных, появление несогласованных данных и появление строк-призраков.


evvcom   (2008-09-05 08:38:00) [24]

еще один универсал? :-)


Petr V. Abramov   (2008-09-04 23:12:00) [25]


> Мне же нужен по возможности универсальный вариант, ну пусть
> хотя бы одинаково работающий в Access, MySQL, MSSQL, Oracle.
>  

для перечисленных СУБД оптимального универсального варианта нет.


Правильный$Вася   (2008-09-04 22:58:00) [26]


> сократить вероятность можно

можно
но при наличии отличной от нуля вероятности такой метод можно смело сливать в унитаз


stas   (2008-09-04 22:46:00) [27]

Правильный$Вася   (04.09.08 22:14) [59]
Может, есть уровни блокировки, хотя это уже будет не универсальный метод.
сократить вероятность можно добавлением условия и перечислением в условии всех вставленных полей т.е.

Insert into Table (F1,F2,F3) Values (@F1,@F2,@F3)
Select select Max(ID)  from Table WHERE F1=@F1 AND F2=@F2 AND F3=@F3


В некотрых случаях возможность получения чужого ID снижатся до 0, в некоторых остается. Так же как и в любом из предложеных методов.


Правильный$Вася   (2008-09-04 22:14:00) [28]


> stas ©   (04.09.08 21:58) [58]

дудки
другая транзакция (от другого подключения) может запросто закончиться где-нить между Insert и select, в результате ты увидишь чужой id


stas   (2008-09-04 21:58:00) [29]

Правильный$Вася   (04.09.08 17:43) [52]

> begin tran
> Declare @ID int
> Insert into Table (....) Values ( ...)
> Select @ID=select Max(ID)  from Table;
> commit tran

Это пройдет в рамках одной транзакции, что исключает между инструкциями выполнение другой транзакции


stas   (2008-09-04 21:41:00) [30]

Ega23 ©   (04.09.08 18:39) [56]

я предлагал так:
Declare @ID int;
Insert into Table (....) Values ( ...)
Select @ID=select Max(ID)  from Table;


Ega23   (2008-09-04 18:39:00) [31]


> Олег, ты заголовок темы забыл :)
> а зачем - так хотя бы для того, чтобы использовать его в
> других таблицах в рамках транзакции


Declare @ID int;
Select @ID=IsNull(Max(ID) + 1, 1) from Table;
Insert into Table (ID, ....) Values (@ID, ...)


Только так, по-другому низя....


Правильный$Вася   (2008-09-04 18:25:00) [32]


> Зачем мне ID "последней вставленной записи"?

Олег, ты заголовок темы забыл :)
а зачем - так хотя бы для того, чтобы использовать его в других таблицах в рамках транзакции

> И что будет, если таблица пустая?

вряд ли она будет пустая, если запись только что добавили (хотя варианты есть, конечно)


Ega23   (2008-09-04 18:01:00) [33]


> зачем +1 это же не будет ID последней вставленной записи.


Зачем мне ID "последней вставленной записи"?
И что будет, если таблица пустая?


stas   (2008-09-04 17:48:00) [34]

Ega23 ©   (04.09.08 17:43) [51]
зачем +1 это же не будет ID последней вставленной записи.


Правильный$Вася   (2008-09-04 17:43:00) [35]


> определить последнию вставленную запись универсальным методом
> можноselect max(ID) from mytable в рамках одной транзакции

только в однопользовательскомслучае, не бывает междупользовательских транзакций
в остальных случаях последняя вставленная может быть совсем не твоя
мало того, если инкремент делать -1, то и не max вовсе нужно использовать


Ega23   (2008-09-04 17:43:00) [36]


> 1. Гарантирует уникальность автоинкримент


1. Не гарантирует (для MSSQL способы "ломания" я уже приводил. Есть и другие).
2. Есть далеко не везде.
3. select max(ID) Если уж взялся такое писать, то пиши как положено:
select IsNull(max(ID) + 1, 1)


stas   (2008-09-04 17:37:00) [37]

1. Гарантирует уникальность автоинкримент
2. определить последнию вставленную запись универсальным методом можно
select max(ID) from mytable в рамках одной транзакции
и без извращений описаных в Ega23 ©   (04.09.08 13:31) [31]
если так рассуждать можно любой метод завалить
3. Давать глупые советы и доказывать что они умные еще глупее тем более если у тебя в анкете буква M
4. чем глупее [5] чем [39] обоснуй пожалуйста
5. Попробуйте доказать обратное 1 и 2.


Правильный$Вася   (2008-09-04 17:31:00) [38]


> Почему в первом же посте не сказали, что ЭТО НЕВОЗМОЖНО

да ну? я ж сказал - бессмысленно


Курдль   (2008-09-04 17:27:00) [39]


> Johnmen ©   (04.09.08 17:12) [46]
> Перечитай постановку вопроса автора ветки.


Я именно поэтому привел цитату из Кин-дза-дзы.
Ну, автор решил осчастливить мир каким-нибудь компонентом, который "может все".
А вы-то что? Почему в первом же посте не сказали, что ЭТО НЕВОЗМОЖНО.
Почитайте спец. литературу по СУБД и найдите там "альтернативные" варианты получения уникальных идентификаторов.


Johnmen   (2008-09-04 17:13:00) [40]

> Какой "клиент" может дать вам гарантированно уникальный
> идентификатор (не GUID)?
Кстати, и GUID не гарантирует...


Страницы:   1 2 3 4 5

Наверх

Титульная страница Поиск, карта сайта Написать письмо