Форум: "Базы";
Текущий архив: 2010.03.28;
Скачать: [xml.tar.bz2];
ВнизID последней добавленной записи Найти похожие ветки
← →
Ega23 © (2008-09-04 16:46) [40]
> более глупого поста чем Johnmen © (04.09.08 13:34) [32]
> в этой ветке небыло.
Вообще-то он как бы по делу спросил...
← →
Курдль (2008-09-04 16:52) [41]Жаль, что нельзя вставить в цитату все посты в этой ветке...
Куда катится мир? До чего довел планету этот фигляр Пэжэ?!!
> stas © (04.09.08 16:40) [39]
>
> Johnmen © (04.09.08 16:34) [38]
> более глупого поста чем Johnmen © (04.09.08 13:34) [32]
> в этой ветке небыло.
БЫЛО!!! Вот это:
> stas © (04.09.08 12:22) [5]
>
> DVM © (04.09.08 12:03)
> наверное такой:
> после вставки
> select max(ID) from mytable
Хотя они друг друга стоят.
← →
Johnmen © (2008-09-04 16:57) [42]
> stas © (04.09.08 16:40) [39]
> Johnmen © (04.09.08 16:34) [38]более глупого поста чем
> Johnmen © (04.09.08 13:34) [32]в этой ветке небыло.
Это ты так думаешь на основании своих убогих знаний и нулевого опыта.
> Курдль (04.09.08 16:52) [41]
> Хотя они друг друга стоят.
Не стОит право ровнять моё предложение [32] с [5].
А то могу подумать грустное про тебя...:)
← →
Правильный$Вася (2008-09-04 17:01) [43]пошли разборки, пора закрываться
← →
Ega23 © (2008-09-04 17:01) [44]
> Хотя они друг друга стоят.
А в чём проблема генерации ID на клиенте? Искренне не понимаю...
← →
Курдль (2008-09-04 17:08) [45]Какой "клиент" может дать вам гарантированно уникальный идентификатор (не GUID)?
Какой запрос гарантированно защитит вас от многопользовательской коллизии?
Зачем СУБД городили все эти генераторы, последовательности, автоинкременты и т.п.?
← →
Johnmen © (2008-09-04 17:12) [46]
> Какой "клиент" может дать вам гарантированно уникальный
> идентификатор (не GUID)?
А этого и не требуется :)
> Какой запрос гарантированно защитит вас от многопользовательской коллизии?
Не запрос. А возвращаемая сервером ошибка.
> Зачем СУБД городили все эти генераторы, последовательности,
> автоинкременты и т.п.?
Перечитай постановку вопроса автора ветки.
ЗЫ
Начинаешь огорчать...:(
← →
Johnmen © (2008-09-04 17:13) [47]> Какой "клиент" может дать вам гарантированно уникальный
> идентификатор (не GUID)?
Кстати, и GUID не гарантирует...
← →
Курдль (2008-09-04 17:27) [48]
> Johnmen © (04.09.08 17:12) [46]
> Перечитай постановку вопроса автора ветки.
Я именно поэтому привел цитату из Кин-дза-дзы.
Ну, автор решил осчастливить мир каким-нибудь компонентом, который "может все".
А вы-то что? Почему в первом же посте не сказали, что ЭТО НЕВОЗМОЖНО.
Почитайте спец. литературу по СУБД и найдите там "альтернативные" варианты получения уникальных идентификаторов.
← →
Правильный$Вася (2008-09-04 17:31) [49]
> Почему в первом же посте не сказали, что ЭТО НЕВОЗМОЖНО
да ну? я ж сказал - бессмысленно
← →
stas © (2008-09-04 17:37) [50]1. Гарантирует уникальность автоинкримент
2. определить последнию вставленную запись универсальным методом можно
select max(ID) from mytable в рамках одной транзакции
и без извращений описаных в Ega23 © (04.09.08 13:31) [31]
если так рассуждать можно любой метод завалить
3. Давать глупые советы и доказывать что они умные еще глупее тем более если у тебя в анкете буква M
4. чем глупее [5] чем [39] обоснуй пожалуйста
5. Попробуйте доказать обратное 1 и 2.
← →
Ega23 © (2008-09-04 17:43) [51]
> 1. Гарантирует уникальность автоинкримент
1. Не гарантирует (для MSSQL способы "ломания" я уже приводил. Есть и другие).
2. Есть далеко не везде.
3. select max(ID) Если уж взялся такое писать, то пиши как положено:select IsNull(max(ID) + 1, 1)
← →
Правильный$Вася (2008-09-04 17:43) [52]
> определить последнию вставленную запись универсальным методом
> можноselect max(ID) from mytable в рамках одной транзакции
только в однопользовательском случае, не бывает междупользовательских транзакций
в остальных случаях последняя вставленная может быть совсем не твоя
мало того, если инкремент делать -1, то и не max вовсе нужно использовать
← →
stas © (2008-09-04 17:48) [53]Ega23 © (04.09.08 17:43) [51]
зачем +1 это же не будет ID последней вставленной записи.
← →
Ega23 © (2008-09-04 18:01) [54]
> зачем +1 это же не будет ID последней вставленной записи.
Зачем мне ID "последней вставленной записи"?
И что будет, если таблица пустая?
← →
Правильный$Вася (2008-09-04 18:25) [55]
> Зачем мне ID "последней вставленной записи"?
Олег, ты заголовок темы забыл :)
а зачем - так хотя бы для того, чтобы использовать его в других таблицах в рамках транзакции
> И что будет, если таблица пустая?
вряд ли она будет пустая, если запись только что добавили (хотя варианты есть, конечно)
← →
Ega23 © (2008-09-04 18:39) [56]
> Олег, ты заголовок темы забыл :)
> а зачем - так хотя бы для того, чтобы использовать его в
> других таблицах в рамках транзакцииDeclare @ID int;
Select @ID=IsNull(Max(ID) + 1, 1) from Table;
Insert into Table (ID, ....) Values (@ID, ...)
Только так, по-другому низя....
← →
stas © (2008-09-04 21:41) [57]Ega23 © (04.09.08 18:39) [56]
я предлагал так:Declare @ID int;
Insert into Table (....) Values ( ...)
Select @ID=select Max(ID) from Table;
← →
stas © (2008-09-04 21:58) [58]Правильный$Вася (04.09.08 17:43) [52]
> begin tran
> Declare @ID int
> Insert into Table (....) Values ( ...)
> Select @ID=select Max(ID) from Table;
> commit tran
Это пройдет в рамках одной транзакции, что исключает между инструкциями выполнение другой транзакции
← →
Правильный$Вася (2008-09-04 22:14) [59]
> stas © (04.09.08 21:58) [58]
дудки
другая транзакция (от другого подключения) может запросто закончиться где-нить между Insert и select, в результате ты увидишь чужой id
← →
stas © (2008-09-04 22:46) [60]Правильный$Вася (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:58) [61]
> сократить вероятность можно
можно
но при наличии отличной от нуля вероятности такой метод можно смело сливать в унитаз
← →
Petr V. Abramov © (2008-09-04 23:12) [62]
> Мне же нужен по возможности универсальный вариант, ну пусть
> хотя бы одинаково работающий в Access, MySQL, MSSQL, Oracle.
>
для перечисленных СУБД оптимального универсального варианта нет.
← →
evvcom © (2008-09-05 08:38) [63]еще один универсал? :-)
← →
oleg_at (2009-03-11 14:01) [64]Уважаемый Правильный$Вася!
Вы теоретик или практик?
Во первых чтоб рассуждать о транзакциях, нужно уточнить - какой уровень?
Во-вторых, есть такое
mysql_insert_id
mysql_insert_id -- Получает id сгенерированный предыдущим выполнением sql-запроса insert
И в третьих, все ваши, а вдруг похожи на,
"А кто пробовол съесть слона"!
P.S. читайте Маркса:
В стандарте SQL определены четыре уровня изоляции: READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ и SERIALIZABLE. Они перечислены в порядке увеличения изолированности и по очереди решают три основные проблемы, возникающие при использовании транзакций: появление промежуточных данных, появление несогласованных данных и появление строк-призраков.
← →
Sergey13 © (2009-03-11 14:31) [65]> [64] oleg_at (11.03.09 14:01)
Ну дал Бог! Пришел мессия! Всего то полгода ждали.
8-)
← →
Кщд (2009-03-11 14:52) [66]>oleg_at (11.03.09 14:01) [64]
>В стандарте SQL определены четыре уровня изоляции: READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ и SERIALIZABLE.
это всё просто великолепно
но Вы уверены, что каждая из перечисленных у топикстартера СУБД поддерживает все эти уровни?
и уверены ли Вы, что эти уровни в указанных СУБД соответствуют стандарту ANSI на 100%?)
← →
фыва (2009-03-11 19:57) [67]
> >В стандарте SQL определены четыре уровня изоляции: READ
> UNCOMMITTED, READ COMMITTED, REPEATABLE READ и SERIALIZABLE.
ссылку на данное утверждение в стандарте SQL, пожалйста
← →
YurikGL © (2009-03-11 20:09) [68]В свое время в IB делал по хранимке на каждую таблицу. Входные параметры - значения полей, а на выходе был присвоенный id-к. Внутри хранимки вызывался генератор, потом с полученным значением делался insert в таблицу и то же значение возвращалось процедурой.
← →
YurikGL © (2009-03-11 20:15) [69]вот... даже код нашел
CREATE PROCEDURE ADDUPR (
naimenovan varchar(50),
primech varchar(200))
returns (
id integer)
as
begin
ID = gen_id(g_upr, 1);
insert into upr (IdUpr,Naimenovan,Primech) values(:ID,:NAIMENOVAN,:primech);
end
← →
Кщд (2009-03-12 06:36) [70]>фыва (11.03.09 19:57) [67]
ссылка нужна для подтверждения весьма спорного утверждения
здесь же достаточно просто открыть документацию по стандарту ANSI SQL 99
← →
Ega23 © (2009-03-12 10:14) [71]
> В свое время в IB делал по хранимке на каждую таблицу. Входные
> параметры - значения полей, а на выходе был присвоенный
> id-к. Внутри хранимки вызывался генератор, потом с полученным
> значением делался insert в таблицу и то же значение возвращалось
> процедурой.
>
Я вообще всегда так делаю, что под MSSQL, что под Postgres. Очень удобно.
← →
Ega23 © (2009-03-12 10:17) [72]
> ANSI SQL 99
Староват стандарт. ЕМНИП, как минимум 2003 года уже был. А возможно и позже, там дополнения где-то раз в год-полтора выходят..
← →
Кщд (2009-03-12 11:49) [73]>Ega23 © (12.03.09 10:17) [72]
это был пример навскидку(92 читал наискосок; 2003-ий, увы мне, не читал вовсе; учился по 99-му - поэтому его и привел), где точно упоминается об уровнях изоляции
очень не думаю, что в 2003-ем стандарте произошли изменения по части уровней изоляции
← →
Cobalt © (2009-03-12 13:28) [74]Первое решение, для Insert:
В таблицу добавляете поле varchar
при вставке туда записывается GUID
После вставки делается выборка ID-ка по этому GUID
Потом это GUID-поле можно/нужно очистить
Работает для одной записи, на любых базах.
Полагаю, что и для нескольких записей такой алгоритм тоже сработает.
Второе решение, с использованием таблицы, куда делается вставка:
Полагаю, что проще будет использовать Таблицу, и делать в неё вставку. а после Post читать поле ID.
← →
Ega23 © (2009-03-12 13:40) [75]GUID не все базы поддерживают.
GUID не все базу умеют генерить
← →
Кщд (2009-03-12 13:51) [76]>Cobalt © (12.03.09 13:28) [74]
>Полагаю, что проще будет использовать Таблицу, и делать в неё вставку. а после Post читать поле ID.
это как?
← →
Cobalt © (2009-03-12 14:02) [77]
> Ega23 © (12.03.09 13:40) [75]
GUID будет генерить клиент, который, собственно, и хочет знать Id-ик только что вставленной им же записи.
А varchar, полагаю, у всех баз есть.
Условно:ExecSQL("Insert into mytable (name, guid) values ("Pupkin", "{54788324-43431254-53-5235-25-2}")
Затем
MyQuery.SQL.Text := "Select ID from mytable
where guid = ""{54788324-43431254-53-5235-25-2}""""
id := MyQuery.ParamByName("id").AsInteger;
> Кщд (12.03.09 13:51) [76]
>
> >Cobalt © (12.03.09 13:28) [74]
> >Полагаю, что проще будет использовать Таблицу, и делать
> в неё вставку. а после Post читать поле ID.
> это как?
что-то типа такого:
With MyTable do
begin
Insert;
FieldByName("name") := "pupkin";
FieldByName("guid") := "{54788324-43431254-53-5235-25-2}";
Post;
id := FieldByName("id");
end;
← →
Cobalt © (2009-03-12 14:04) [78]2 Кщд (12.03.09 13:51) [76]
P.S.
Если, конечно, таблица не откладывает изменения на клиенте, а сразу производит запись в базу.
← →
Ega23 © (2009-03-12 14:11) [79]
> Cobalt © (12.03.09 14:02) [77]
Вот теперь прикинь: в таблице миллион записей. Да пусть даже не миллион, а 10000. Сколько у тебя займёт поиск по точному сравнению строк?
← →
Cobalt © (2009-03-12 14:27) [80]
> Ega23 © (12.03.09 14:11) [79]
> Вот теперь прикинь: в таблице миллион записей. Да пусть даже не миллион,
> а 10000. Сколько у тебя займёт поиск по точному сравнению строк?
А это уже второй вопрос, профессор :-)
За всё надо платить.
И потом, можно это поле очищать сразу же по получению ID, и индекс по нему (Guid-у) строить.
Или воспользоваться вторым вариантом.
Главное требование было - работоспособность на разных базах.
Страницы: 1 2 3 вся ветка
Форум: "Базы";
Текущий архив: 2010.03.28;
Скачать: [xml.tar.bz2];
Память: 0.61 MB
Время: 0.006 c