Главная страница
    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]
> в этой ветке небыло.


Вообще-то он как бы по делу спросил...



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

Форум: "Базы";
Текущий архив: 2010.03.28;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.55 MB
Время: 0.006 c
2-1264710471
Делфиец
2010-01-28 23:27
2010.03.28
Как заблокировать новигацию в таблице?


4-1230628147
Panzer
2008-12-30 12:09
2010.03.28
Как можно отлавливать обращения к реестру другими приложениями?


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


15-1262726157
Jeer
2010-01-06 00:15
2010.03.28
Календарное светопреставление


1-1244994785
RWolf
2009-06-14 19:53
2010.03.28
D5: "step into" в код DLL





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский