![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
ID последней добавленной записи [D7, любая СУБД]
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 не гарантирует...