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-17 12:15:00) [1]

>clickmaker ©   (12.03.09 14:36) [82]
это чем-то лучше GUID?
пример?


Кщд   (2009-03-17 12:04:00) [2]

>Cobalt ©   (12.03.09 14:49) [83]
>1. всякое удобство чего-то стОит. кстати, можно и протестировать скорость, >прежде чем прислушиваться к советам всяких там... ;-)
почему бы, собственно, не использовать GUID в качестве ID?
к чему все эти пляски с очисткой и поиском ID?
про псевдоуникальность GUID давно уже поперетерли - да, конфликт возможен, но крайнемаловероятен

>2. Если в индексе одновременно (в течении долей секунды) будет не более >пару записей - то, полагаю, незначительно.
в некоторых СУБД null-значения хранятся в индексе


Petr V. Abramov   (2009-03-12 15:12:00) [3]


> Не слишком-ли шикарно, а?

зато СУБД-независимо ;)


Cobalt   (2009-03-12 14:49:00) [4]


> Ega23 ©   (12.03.09 14:36) [81]
>
> > И потом, можно это поле очищать сразу же по получению ID,
> >  и индекс по нему (Guid-у) строить.
>
> 1. Если очищать, то у тебя процесс добавления записи выливается
> в 3 отдельных запроса: Insert, Select, Update. Не слишком- ли шикарно, а?
> 2. Строить индекс по строковому полю - это сильно. Прикинь,
>  сколько вставка (с перестроением индекса) будет занимать?
>

1. всякое удобство чего-то стОит. кстати, можно и протестировать скорость, прежде чем прислушиваться к советам всяких там... ;-)
2. Если в индексе одновременно (в течении долей секунды) будет не более пару записей - то, полагаю, незначительно.


Ega23   (2009-03-12 14:36:00) [5]


> И потом, можно это поле очищать сразу же по получению ID,
>  и индекс по нему (Guid-у) строить.


1. Если очищать, то у тебя процесс добавления записи выливается в 3 отдельных запроса: Insert, Select, Update. Не слишком-ли шикарно, а?
2. Строить индекс по строковому полю - это сильно. Прикинь, сколько вставка (с перестроением индекса) будет занимать?


clickmaker   (2009-03-12 14:36:00) [6]

> [0] DVM ©   (04.09.08 12:03)

используй дату в качестве основы для генерации Ид. На клиенте.


Cobalt   (2009-03-12 14:27:00) [7]


> Ega23 ©   (12.03.09 14:11) [79]
> Вот теперь прикинь: в таблице миллион записей. Да пусть даже не миллион,
> а 10000. Сколько у тебя займёт поиск по точному сравнению строк?

А это уже второй вопрос, профессор :-)

За всё надо платить.
И потом, можно это поле очищать сразу же по получению ID, и индекс по нему (Guid-у) строить.

Или воспользоваться вторым вариантом.

Главное требование было - работоспособность на разных базах.


Ega23   (2009-03-12 14:11:00) [8]


> Cobalt ©   (12.03.09 14:02) [77]


Вот теперь прикинь: в таблице миллион записей. Да пусть даже не миллион, а 10000. Сколько у тебя займёт поиск по точному сравнению строк?


Cobalt   (2009-03-12 14:04:00) [9]

2 Кщд   (12.03.09 13:51) [76]
P.S.
Если, конечно, таблица не откладывает изменения на клиенте, а сразу производит запись в базу.


Cobalt   (2009-03-12 14:02:00) [10]


> 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;


Кщд   (2009-03-12 13:51:00) [11]

>Cobalt ©   (12.03.09 13:28) [74]
>Полагаю, что проще будет использовать Таблицу, и делать в неё вставку. а после Post читать поле ID.
это как?


Ega23   (2009-03-12 13:40:00) [12]

GUID не все базы поддерживают.
GUID не все базу умеют генерить


Cobalt   (2009-03-12 13:28:00) [13]

Первое решение, для Insert:
В таблицу добавляете поле varchar
при вставке туда записывается GUID
После вставки делается выборка ID-ка по этому GUID

Потом это GUID-поле можно/нужно очистить

Работает для одной записи, на любых базах.
Полагаю, что и для нескольких записей такой алгоритм тоже сработает.

Второе решение, с использованием таблицы, куда делается вставка:
Полагаю, что проще будет использовать Таблицу, и делать в неё вставку. а после Post читать поле ID.


Кщд   (2009-03-12 11:49:00) [14]

>Ega23 ©   (12.03.09 10:17) [72]
это был пример навскидку(92 читал наискосок; 2003-ий, увы мне, не читал вовсе; учился по 99-му - поэтому его и привел), где точно упоминается об уровнях изоляции
очень не думаю, что в 2003-ем стандарте произошли изменения по части уровней изоляции


Ega23   (2009-03-12 10:17:00) [15]


> ANSI SQL 99


Староват стандарт. ЕМНИП, как минимум 2003 года уже был. А возможно и позже, там дополнения где-то раз в год-полтора выходят..


Ega23   (2009-03-12 10:14:00) [16]


> В свое время в IB делал по хранимке на каждую таблицу. Входные
> параметры - значения полей, а на выходе был присвоенный
> id-к. Внутри хранимки вызывался генератор, потом с полученным
> значением делался insert  в таблицу и то же значение возвращалось
> процедурой.
>


Я вообще всегда так делаю, что под MSSQL, что под Postgres. Очень удобно.


Кщд   (2009-03-12 06:36:00) [17]

>фыва   (11.03.09 19:57) [67]
ссылка нужна для подтверждения весьма спорного утверждения
здесь же достаточно просто открыть документацию по стандарту ANSI SQL 99


YurikGL   (2009-03-11 20:15:00) [18]

вот... даже код нашел

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


YurikGL   (2009-03-11 20:09:00) [19]

В свое время в IB делал по хранимке на каждую таблицу. Входные параметры - значения полей, а на выходе был присвоенный id-к. Внутри хранимки вызывался генератор, потом с полученным значением делался insert  в таблицу и то же значение возвращалось процедурой.


фыва   (2009-03-11 19:57:00) [20]


> >В стандарте SQL определены четыре уровня изоляции: READ
> UNCOMMITTED, READ COMMITTED, REPEATABLE READ и SERIALIZABLE.

ссылку на данное утверждение в стандарте SQL, пожалйста


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

Наверх

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