Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2010.03.28;
Скачать: CL | DM;

Вниз

ID последней добавленной записи   Найти похожие ветки 

 
DVM ©   (2008-09-04 12:03) [0]

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

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

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


 
Правильный$Вася   (2008-09-04 12:07) [1]


> Мне же нужен по возможности универсальный вариант

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


 
Ega23 ©   (2008-09-04 12:12) [2]


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


1. Сам тип автоинкримента может быть разным (int  и bigint, serial и bigserial и т.п.).
2. Его (автоинкримента) может и не быть как такового в СУБД.
3. И GUID СУБД тоже может не уметь генерить (например, Postgres в поставке по-умолчанию не умеет, т.к. есть несколько способов).

Я бы в такой ситуации на клиенте какое-нибудь уникальное значение генерил.


 
DVM ©   (2008-09-04 12:14) [3]


> слишком бессмысленно

Может и бессмысленно, но хотелось бы абстрагировать несложное ПО от конкретной СУБД. Или хотя бы свести к минимуму переделки под другую СУБД.


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

такая мысль была, но комбинации полей не уникальны.


 
DVM ©   (2008-09-04 12:18) [4]


> Ega23 ©   (04.09.08 12:12) [2]


> 1. Сам тип автоинкримента может быть разным (int  и bigint,
>  serial и bigserial и т.п.).

Ну int или подобный есть везде вроде.


> 2. Его (автоинкримента) может и не быть как такового в СУБД.

Я не замахиваюсь на вообще все СУБД. В тех что я написал есть по крайней мере.


> 3. И GUID СУБД тоже может не уметь генерить (например, Postgres
> в поставке по-умолчанию не умеет, т.к. есть несколько способов).
>

Так сам генерить буду и в запрос буду пихать.


> Я бы в такой ситуации на клиенте какое-нибудь уникальное
> значение генерил.

Да я помню ветку про GUID-ы. Пока рассматриваю как основной вариант. Хотя совпадения возможные совсем не радуют.


 
stas ©   (2008-09-04 12:22) [5]

DVM ©   (04.09.08 12:03)
наверное такой:
после вставки
select max(ID) from mytable


 
Игорь Шевченко ©   (2008-09-04 12:24) [6]


> Писать разный код для разных СУБД?


Да


 
DVM ©   (2008-09-04 12:25) [7]


> stas ©   (04.09.08 12:22) [5]


> select max(ID) from mytable
>

А если между моей вставкой и последующим выполнение этого запроса другой клиент добавит еще запись? Я получу не свой ID.


 
b z   (2008-09-04 12:28) [8]


> Ввести свое доп. поле в которое пихать собственноручно сгенерированное
> чудо типа GUID и сразу после добавления находить запись
> по этому полю?
А ... зачем при этом "автоинкрементное поле счетчик" ?


 
DVM ©   (2008-09-04 12:31) [9]


> А ... зачем при этом "автоинкрементное поле счетчик" ?
>

Тогда ID собственно станет не нужен, использоваться будет это дополнительное поле в качестве ключевого.


 
Ega23 ©   (2008-09-04 12:31) [10]


> stas ©   (04.09.08 12:22) [5]
>
> DVM ©   (04.09.08 12:03)
> наверное такой:
> после вставки
> select max(ID) from mytable


Расстрелять из пулемёта за такое.
Кстати, он может быть и не Max, то таки быть уникальным. Об этом не думал?


 
Ega23 ©   (2008-09-04 12:32) [11]


> Кстати, он может быть и не Max, но таки быть уникальным.
>  Об этом не думал?


 
Sergey13 ©   (2008-09-04 12:32) [12]

Может быть сделать некую одинаковую функцию во всех СУБД, которая будет работать с таблицей, хранящей текущие идентификаторы всех талиц в БД? Хотя наверное конкуренция за эту таблицу получится сумашедшая в приличных размеров системе.


 
DVM ©   (2008-09-04 12:36) [13]


> Sergey13 ©   (04.09.08 12:32) [12]
>
> Может быть сделать некую одинаковую функцию во всех СУБД,
>  которая будет работать с таблицей, хранящей текущие идентификаторы
> всех талиц в БД?

Не очень понял. Поясни.


 
Ega23 ©   (2008-09-04 12:37) [14]


> Да я помню ветку про GUID-ы. Пока рассматриваю как основной
> вариант. Хотя совпадения возможные совсем не радуют.


Там GUID-ы (точнее - аналог) совсем по-другой причине использовались: нужна была уникальная идентификация сущности не в рамках одного комплекса, а вообще, глобально.


 
Правильный$Вася   (2008-09-04 12:37) [15]


>  хотелось бы абстрагировать несложное ПО от конкретной СУБД

если это несложное по однопользовательское, то очень осторожно можно использовать MAX, хотя любое однопользовательское имеет тенденцию к переходу в многопользовательскую
но тогда появляется желание выжать больше из СУБД, но на абстракной СУБД больше выжать нельзя, появляется специфика, а тут уже никакой абстрактности, сплошная конкретика


 
Ega23 ©   (2008-09-04 12:38) [16]


> Не очень понял. Поясни.


Ну что-то типа интербэйзного генератора


 
b z   (2008-09-04 12:41) [17]


> Хотя наверное конкуренция за эту таблицу получится сумашедшая
> в приличных размеров системе.
"Каждой твари по паре" :)


 
DVM ©   (2008-09-04 12:44) [18]


> Правильный$Вася   (04.09.08 12:37) [15]

Все верно. ПО относительно несложное, но многопользовательское все же.


 
Правильный$Вася   (2008-09-04 12:45) [19]


> Может быть сделать некую одинаковую функцию во всех СУБД

не все субд поддерживают функции, да и способ их вызова различен


 
Ega23 ©   (2008-09-04 12:51) [20]


> Все верно. ПО относительно несложное, но многопользовательское
> все же.


выноси общение с СУБД на уровень абстракции. Для каждой - реализация своя; то, что с этой абстракцией работает, про СУБД ничего не знает.
В конце-концов, ключевое поле на клиенте - вещь вообще абстрактнее некуда.


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


> Ega23 ©   (04.09.08 12:51) [20]

да, по сути - нужен модуль-посредник, который для каждой субд будет свой, а интерфейс к нему от основной функциональности - единый


 
Ega23 ©   (2008-09-04 13:00) [22]


> да, по сути - нужен модуль-посредник, который для каждой
> субд будет свой, а интерфейс к нему от основной функциональности
> - единый


Угу.


 
stas ©   (2008-09-04 13:05) [23]

>DVM ©   (04.09.08 12:25) [7]
Заключить в одну транзакцию.

>Ega23 ©   (04.09.08 12:32) [11]
может конечно быть минимальным

>Ega23 ©   (04.09.08 12:31) [10]
>Расстрелять из пулемёта за такое.
Возможно, но это единственный  способ, который будет работать с любой БД.


 
Игорь Шевченко ©   (2008-09-04 13:06) [24]


> Возможно, но это единственный  способ, который будет работать
> с любой БД.


ты бредишь


 
Sergey13 ©   (2008-09-04 13:09) [25]

> [13] DVM ©   (04.09.08 12:36)
> Не очень понял. Поясни.

Ну в принципе

> [16] Ega23 ©   (04.09.08 12:38)
> Ну что-то типа интербэйзного генератора

Есть таблица с двумя полями Table_name и Current_Id. Пишется функция, которая на входе получает имя таблицы а на выходе отдает текущее знгачение+1, меняя содержимое соответствующего поля. Все ключи заполняются через эту функцию. Опросив текущее значение получаешь искомое.
Но это не решение - это идея для решения. Потому что это надо очень задуматься о конкуренции на эту таблицу.


 
Ega23 ©   (2008-09-04 13:18) [26]


> может конечно быть минимальным


1. Ты удивишься, но я тебе могу написать запрос для MSSQL, который будет вставлять значение в "дырку" для Identity-поля.
2. Ключ и не автоинкриментом может быть. Но при этом не перестаёт быть ключом.


 
Ega23 ©   (2008-09-04 13:19) [27]


> ты бредишь


+1


 
DVM ©   (2008-09-04 13:24) [28]


> Sergey13 ©   (04.09.08 13:09) [25]

Теперь ясно, спасибо.


 
stas ©   (2008-09-04 13:28) [29]

Ega23 ©   (04.09.08 13:18) [26]

1. Ты уверен что scope_identity() в этом варианте тебе вернет верное значение?
2.

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


 
Правильный$Вася   (2008-09-04 13:29) [30]


> stas ©   (04.09.08 13:28) [29]

это автоинкрементное поле счетчик (ID) только в голове автора, т.к. СУБД абстрактная, то это не более, чем идея, а не способ реализации


 
Ega23 ©   (2008-09-04 13:31) [31]


> 1. Ты уверен что scope_identity() в этом варианте тебе вернет
> верное значение?


А ты уверен, что scope_identity() тебе вообще что-то вернёт в этом случае?
смотри в сторону SET IDENTITY_INSERT ON/OFF


 
Johnmen ©   (2008-09-04 13:34) [32]


> DVM ©   (04.09.08 12:03) 

В данных условиях я бы генерил уникальное значение на клиенте. (Ну понятное дело, что не 100% уникальное:))

> Игорь Шевченко ©   (04.09.08 13:06) [24]
> ты бредишь

Причем делает это перманентно в на разные темы...


 
stas ©   (2008-09-04 13:49) [33]

Ega23 ©   (04.09.08 13:31) [31]
Ну, так тогда о чем вообще разговор?
Узнать в любой базе последний вставленый ID?  
а если было сразу вставлено 5 строк?
а как решит проблему модуль-посредник если этот ID надо использовать в дальнеших инструкциях запроса?
И насколько сложная и ответственная задача чтобы это все городить?
Johnmen ©   (04.09.08 13:34) [32]
генеальное решение. :-D


 
Ega23 ©   (2008-09-04 14:31) [34]


> а как решит проблему модуль-посредник если этот ID надо
> использовать в дальнеших инструкциях запроса?


Если надо использовать - то используй, тебе никто не мешает.

declare @ID uniqueidentifier;
Set @ID=:ID
Set NoCount On

Insert into Table1 (ID, .....) Values (@ID, .....);
Insert into Table2 (ID, .....) Values (@ID, .....);
/*
 Используем @ID так, как хочеццо.

*/


 
stas ©   (2008-09-04 14:34) [35]

Ega23 ©   (04.09.08 14:31) [34]

Типа такого:
declare @ID  int
Insert into...
Set @ID=scope_identity()

Insert into ... Values (@ID)


 
Ega23 ©   (2008-09-04 14:45) [36]


> Типа такого:


Что типа такого? Ещё раз: я могу в таблицу с Identity-полем вставить в "дырку" ключевое значение, отключив на время Identity. И твой скрипт в этом случае:
а) пойдёт лесом.
б) даже если и не пойдёт, то будет работать только под mssql.


 
stas ©   (2008-09-04 16:26) [37]

Ega23 ©   (04.09.08 14:45) [36]

1. Опять же,  что автору требуется?
2. Какой скрипт не пойдет лесом?


 
Johnmen ©   (2008-09-04 16:34) [38]


> stas ©   (04.09.08 16:26) [37]
> Опять же,  что автору требуется?

Ты не только бредишь в ответах, но и принципиально не читаешь постановку вопроса ветки?
Или же первое - результат второго?
Просто интересно...


 
stas ©   (2008-09-04 16:40) [39]

Johnmen ©   (04.09.08 16:34) [38]
более глупого поста чем Johnmen ©   (04.09.08 13:34) [32]
в этой ветке небыло.


 
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-у) строить.

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

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


 
Ega23 ©   (2009-03-12 14:36) [81]


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


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


 
clickmaker ©   (2009-03-12 14:36) [82]

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

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


 
Cobalt ©   (2009-03-12 14:49) [83]


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

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


 
Petr V. Abramov ©   (2009-03-12 15:12) [84]


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

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


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

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

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


 
Кщд   (2009-03-17 12:15) [86]

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



Страницы: 1 2 3 вся ветка

Текущий архив: 2010.03.28;
Скачать: CL | DM;

Наверх




Память: 0.71 MB
Время: 0.019 c
3-1237275914
hgd
2009-03-17 10:45
2010.03.28
Сохранить в базу картинку


15-1263058858
GanibalLector
2010-01-09 20:40
2010.03.28
Интерфейс


15-1263131112
Студент Игорь
2010-01-10 16:45
2010.03.28
Помогите новичку


2-1264427732
webpauk
2010-01-25 16:55
2010.03.28
Отображение элементов


2-1264681015
d.l.
2010-01-28 15:16
2010.03.28
Сравнить файлы двух папок