Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2010.03.28;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.69 MB
Время: 0.006 c
15-1263072625
Юрий
2010-01-10 00:30
2010.03.28
С днем рождения ! 10 января 2010 воскресенье


1-1245066677
RWolf
2009-06-15 15:51
2010.03.28
чтение из COM-порта - загадочное поведение программы


2-1264114096
Евгений Р.
2010-01-22 01:48
2010.03.28
Как изменить свойство Required поля Access


3-1237289266
Yurikon
2009-03-17 14:27
2010.03.28
Количество записей в TADOTable


2-1264674919
novichek
2010-01-28 13:35
2010.03.28
Image на переднем плане





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский