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

Вниз

получить Insert Id после запроса INSERT...   Найти похожие ветки 

 
123456711   (2008-07-18 13:40) [0]

... у базы Standart Jet DB (Access) через Ado.

Другими словами вставляю строку в таблицу у которой поле [id] - счетчик. Как получить значение этого счетчика после вставки?

Интересует все, кроме метода Select max([id]) FROM [SomeTable].


 
Сергей М. ©   (2008-07-18 13:56) [1]

А другие уникальные ключи у этой таблицы имеются ?
Допускается ли модификация структуры таблицы для решения задачи ?
Допускается ли одновременная работа с таблицей в контексте более чем одной транзакции одновременнно ?


 
Palladin ©   (2008-07-18 13:56) [2]

select @@Identity


 
stas ©   (2008-07-18 14:02) [3]

Palladin ©   (18.07.08 13:56) [2]
Это Access


 
sniknik ©   (2008-07-18 14:09) [4]

> Это Access
да, это все меняет... тогда надо select @@Identity


 
123456711   (2008-07-18 14:16) [5]


> Palladin ©   (18.07.08 13:56) [2]
>
> select @@Identity
>

Спасибо! Как раз то, что нужно!


 
stas ©   (2008-07-18 14:24) [6]

Palladin ©   (18.07.08 13:56) [2]
Работает! незнал.
sniknik ©   (18.07.08 14:09) [4]
ага :)


 
Anatoly Podgoretsky ©   (2008-07-18 15:54) [7]

stas ©   (18.07.08 14:02) [3]
Ты укоряешь или хвастуешься незнанием?


 
MsGuns ©   (2008-07-18 16:15) [8]

Указанный селест должен следовать непосредственно после запроса на вставку в одном и том же TADOCommand, и считывать его через _RecordSet, полученный от него:

var
 cm: TADOCommand;
 ds: TADOQuery;
..

cm := TADOCommand.Create(nil);
cm.Connecton := ..
cm.CommandText := "Insert ...   "+" Select @@indentity";
ds := TADOQuery.Create(nil);
ds.recordset := cm.execute;
NewID :=  ds.recordset.Fields[0].AsInteger;
ds.Free;
cm.Free;

Try .. finally/except сами поставите ;)


 
stas ©   (2008-07-18 16:16) [9]

Anatoly Podgoretsky ©   (18.07.08 15:54) [7]
stas ©   (18.07.08 14:24) [6]


 
sniknik ©   (2008-07-18 16:30) [10]

> Указанный селест должен следовать непосредственно после запроса на вставку в одном и том же TADOCommand, и считывать его через _RecordSet,
> полученный от него:
вовсе не обязательно мудрить с TADOCommand и _RecordSet -ом.
что действительно нужно так это общий конект (TADOConnection) у обоих (TADOCommand, TADODataSet) и синхронное выполнение запросов (что по умолчанию), ну и считывать сразу после вставки само собой.


 
ANB   (2008-07-18 16:42) [11]


> sniknik ©   (18.07.08 16:30) [10]

В мс скл не поможет. Там только в одной команде должно идти.

В аксесс - не знаю.


 
MsGuns ©   (2008-07-18 16:47) [12]

>sniknik ©   (18.07.08 16:30) [10]
>вовсе не обязательно мудрить с TADOCommand и _RecordSet -ом.

Не вижу ничего мудреного. В конце концнв можно написать универсальную функцию и подключить ее к делфе.

>что действительно нужно так это общий конект (TADOConnection) у обоих (TADOCommand, >TADODataSet) и синхронное выполнение запросов (что по умолчанию), ну и считывать сразу >после вставки само собой.

Этого может быть недостаточно


 
sniknik ©   (2008-07-18 16:54) [13]

> В мс скл не поможет.
а не про mssql разговор.

> Этого может быть недостаточно
достаточно с гарантией...


 
stas ©   (2008-07-21 10:38) [14]

ANB   (18.07.08 16:42) [11]
в mssql если есть триггер на таблице на insert в другую таблицу, то и в одной команде непоможет, нужно функцию использовать.


 
Anatoly Podgoretsky ©   (2008-07-21 11:06) [15]

stas ©   (21.07.08 10:38) [14]
Чукча не читатель!
Сказали же, что про mssql речь не идет.


 
stas ©   (2008-07-21 12:07) [16]

Anatoly Podgoretsky ©   (21.07.08 11:06) [15]
Да знаю я.
Ну, раз уж затронули mssql....


 
Dmitry S ©   (2008-07-22 15:02) [17]


> Сказали же, что про mssql речь не идет.

Сори за офтоп.
Вот мне интересно, откуда берется множественное число в подобных фразах. Для преувеличения значимости сказанного? Или это попытка манипуляции с помощью общества?


 
Johnmen ©   (2008-07-22 17:36) [18]


> Dmitry S ©   (22.07.08 15:02) [17]

В соответствии с нормами русского языка. Ничего более.
Для тех, кто писатель, не читатель.


 
Нат   (2008-07-29 11:28) [19]

Как упоминалось можно найти запись по другим ключам.
Например,  если есть поле ДатаВремя создания записи - найти свой ИД по нему, но есть моменты со вставкой и поиском.
Еще можно  Recynс-Requery + bookmark использовать.
Но это все медленнее.


 
Ega23 ©   (2008-07-29 11:52) [20]


> Например,  если есть поле ДатаВремя создания записи - найти
> свой ИД по нему


Не получится.


 
Нат   (2008-07-29 18:56) [21]


> Не получится.

У меня получалось.  Но без изящества.


 
Ega23 ©   (2008-07-30 10:01) [22]


> У меня получалось.


Это просто повезло. На равенство DateTime сверять - глупо, надо на больше-равно - меньше-равно. А так - высока вероятность того, что кто-то ещё кроме тебя успеет это захватить.
В общем, не получится так.


 
Нат   (2008-07-30 10:38) [23]

d := now(); ... insert ... select или look
безо всяких больше либо...
строго равно! до долей секунды
и все получается.


 
Ega23 ©   (2008-07-30 10:44) [24]


> и все получается.


Тебе просто повезло.
1. Ты ещё, похоже, не натыкался на проблему с синхронизацией времени в сети.
2. Ты ещё, похоже, не натыкался на проблему с переходом на зимнее время.


 
Anatoly Podgoretsky ©   (2008-07-30 10:49) [25]

Для подобных дурных подходов есть аппробированое решение - поиск сравнение по всем полям, реализовано в DB.VCL если не применять особых методов, условие не использовать никаких идентифицирующих полей, главное удалить ПК если он есть.


 
Нат   (2008-07-30 11:05) [26]

Подход так себе, через голову.О чем сразу было сказано.
Но работает.
И везение не при чем. Пришлось морщить лоб.
В том случае еще имелось поле Autor, поэтому захватить чужую запись с таким же временем (буде повезет) проблематично.


 
Anatoly Podgoretsky ©   (2008-07-30 11:16) [27]


> и все получается.

Везет.


 
Anatoly Podgoretsky ©   (2008-07-30 11:18) [28]


> Ega23 ©   (30.07.08 10:44) [24]

3. и не понимает устройства типа TDateTime
4. и не понимает принципов работы с плавающей запятой
5. и не понимает принципов работы SQL серверов, где (Fld = Value) <> Value


 
stas ©   (2008-07-30 11:26) [29]

>Нат
Искать по времени свой ID это глупости
1. Быстрее будет уже (Select Max(ID) from mytable).
2. поле датавремя точность до милисекунд, а знаешь сколько транзакций может пройти в одну милисекунду?
3. и зачем изобретать что-то если есть стандартные средства определения ID.


 
Нат   (2008-07-30 11:28) [30]

Я здесь.
Скажите ты, иначе это грубость, профессор.

Я чего не понимаю, стараюсь учиться.


 
Ega23 ©   (2008-07-30 11:30) [31]


> 1. Быстрее будет уже (Select Max(ID) from mytable).


Да нельзя так делать, ёлы-палы!!!
Ну где гарантия того, что это - именно твоя вставка, а не соседнего клиента, который выполнял вставку сразу за тобой??


 
stas ©   (2008-07-30 11:38) [32]

Ega23 ©   (30.07.08 11:30) [31]

Конечно нельзя, но если уж выбирать по дате или (Select Max(ID) from mytable), то лучше последнее.


 
Нат   (2008-07-30 11:47) [33]

Может и глупость, что было-то было... и работало.
Как заметил Ega23,  (Select Max(ID) from mytable) еще менее надежный вариант.
Хотя он гораздо изящнее варианта с датой. Там нужно изголяться в силу

> устройства типа TDateTime

К слову, он был заменен на ... что Вы думаете?
id:=ExecSQL ("Select max([id])+1 FROM [SomeTable]")
TDataSet. Insert(id)
если ошибка - то заново.
И кажется, на так и жило.

Просто был задан вопрос

> Интересует все, кроме метода Select max([id]) FROM [SomeTable].


 
stas ©   (2008-07-30 11:51) [34]

Нат   (30.07.08 11:47) [33]
Так это уже вы автоинкримент выдумываете, а вопрос был как определить значение автоинкремента после вставки.


 
Ega23 ©   (2008-07-30 11:56) [35]

Тогда уж давай будем последовательным:
Select IsNull(max([id])+1, 1) FROM [SomeTable]


 
Нат   (2008-07-30 12:26) [36]


> пределить значение автоинкремента после вставки

Совсем чуть-чуть отклонились.

Ega23
IsNull(max([id])+1, 1) это лучше, но имелось в виду другое.
Принципиальное отличие - вставка не запросом, а DataSet.Insert ...
Т.е. определяем ДО вставки, вставляем и остаемся на нужной записи.
И никаких поисков уже не надо.


 
Ega23 ©   (2008-07-30 12:39) [37]


> Т.е. определяем ДО вставки, вставляем и остаемся на нужной
> записи.


Я понял, что имелось ввиду. Но один фиг, это всё надо одним скриптом делать.
Я Max+1 выберу, а вставку данных в грид ещё не закончу.
В это время Max+1 выберет Вася Пупкин (а значение - то же самое, я ещё данные не закомиттил), быстрее меня забьёт данные, сделает коммит, и я получу insert error.


 
Нат   (2008-07-30 12:56) [38]

Точно. Тогда и все на повтор.

> TDataSet. Insert(id)если ошибка - то заново.

А просто запросом - вообще без гарантии от Васи. Залеты были чаще, чем с датой.
Сложно придумать лучше, чем:

> да, это все меняет... тогда надо select @@Identity

Разве что прямо на серверной стороне... ну там свои штуки.


 
stas ©   (2008-07-30 13:14) [39]

есть @@Identity, чего еще заморачиваться?


 
Anatoly Podgoretsky ©   (2008-07-30 13:30) [40]

> stas  (30.07.2008 11:51:34)  [34]

А там он определен, если ты не заметил.


 
Anatoly Podgoretsky ©   (2008-07-30 13:32) [41]

> Нат  (30.07.2008 12:26:36)  [36]

А нафига Insert - ты думаешь факт определения ИД изменится, если делать вставку с помощью запроса.


 
Anatoly Podgoretsky ©   (2008-07-30 13:33) [42]


> Разве что прямо на серверной стороне... ну там свои штуки.

Где ты нашел серверную сторону в Акцесс?


 
Anatoly Podgoretsky ©   (2008-07-30 13:34) [43]

Кстати а вас не очень занесло с триггерами в Акцесс?


 
Нат   (2008-07-30 13:40) [44]

Серверный курсор имеет место быть, однако с закладки пожелали счастливо оставаться.
Без закладко грид ничего не смог отобразить.
На этом и расстались.
С серверной стороной в Акцессе.


 
stas ©   (2008-07-30 13:56) [45]

Anatoly Podgoretsky ©   (30.07.08 13:30) [40]
где там?
Anatoly Podgoretsky ©   (30.07.08 13:30) [40]-[43]
Разошелся...


 
Anatoly Podgoretsky ©   (2008-07-30 14:48) [46]

> stas  (30.07.2008 13:56:45)  [45]

Читай все обсуждение.


 
Игорь Шевченко ©   (2008-07-30 14:55) [47]

Надо использовать RETURNING. Это правда тоже не в Access-е, но какая нахрен разница ?


 
Sergey13 ©   (2008-07-30 15:10) [48]

> [47] Игорь Шевченко ©   (30.07.08 14:55)

Надо НЕ использовать Access, тогда заработает RETURNING. 8-)


 
Игорь Шевченко ©   (2008-07-30 15:15) [49]

Sergey13 ©   (30.07.08 15:10) [48]

> Надо НЕ использовать Access, тогда заработает RETURNING


Абсолютно верно - Oracle XE наше все :) К тому же там есть средство миграции из Access-а, если мне память не изменяет


 
Ega23 ©   (2008-07-30 15:27) [50]


> Oracle XE наше все :)


Ацтой Оракл, ini-файлы рулят.


 
Игорь Шевченко ©   (2008-07-30 15:40) [51]

Ega23 ©   (30.07.08 15:27) [50]

"Старайтесь избегать «оффтопиков». Добавляя свое сообщение, убедитесь, что оно соответствует обсуждаемой теме"
http://www.delphimaster.ru/forums.shtml#rule


 
Нат   (2008-07-31 03:15) [52]

MsGuns

> cm.CommandText := "Insert ...   "+" Select @@indentity";

А как тебе удалось загнать обе команды в один запрос?
И на какой версии Акцесса?


 
Ega23 ©   (2008-07-31 10:40) [53]


> А как тебе удалось загнать обе команды в один запрос?


А в чём проблема?


ADODataSet1.CommandText := "Set NoCount ON;
Insert into xxx (aName) Values ("111");
Insert into xxx (aName) Values ("222");
Insert into xxx (aName) Values ("333");
Insert into xxx (aName) Values ("444");
Insert into xxx (aName) Values ("555");
Insert into xxx (aName) Values ("666");
Set NoCount OFF;

Select * from xxx";

ADODataSet1.Open;


 
Anatoly Podgoretsky ©   (2008-07-31 11:14) [54]

> Ega23  (31.07.2008 10:40:53)  [53]

Акцесс требует точки с запятой между частями?


 
Ega23 ©   (2008-07-31 11:19) [55]


> Акцесс требует точки с запятой между частями?


Ну это не для Access, это TSQL. А точка с запятой - это уже просто тупо привычка. Многие СУБД требуют. TSQL не требует, но ставить можно.


 
Anatoly Podgoretsky ©   (2008-07-31 13:44) [56]

Ну вообще то тема по Акцесс.
Ладно не знаешь, но не так это и важно. Когда будет важно, то проверка займет несколько секунд.


 
Нат   (2008-07-31 18:09) [57]

В акцессе можно ставить точку с запятой после запроса, однако акцесс не терпит после  больше ничего, т.к. считает ";" завершением инструкции.
Не прокатывает такая конструкция.

Вобчем и без запятой тож не хочет.
Ток по-отдельности.


 
Anatoly Podgoretsky ©   (2008-08-01 09:43) [58]

Ну так в Акцесс, что по отдельности, что вместе результат одинаков - это же файлсерверная БД

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

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

А вот конструкция, для T-SQL или подобных

инструкция1
...
инструкция N


Это одна инструкция и естественно она выполняется как единое целое, на этом кстати основан и SQL Ejection

Не уверен, что это было хорошей идеей.



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

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

Наверх




Память: 0.59 MB
Время: 0.051 c
15-1231816404
Slider007
2009-01-13 06:13
2009.03.29
С днем рождения ! 13 января 2009 вторник


15-1232542679
Marser
2009-01-21 15:57
2009.03.29
Как насчёт KMP?


2-1233394030
Новичек
2009-01-31 12:27
2009.03.29
Установка текста в другом приложении.


15-1233322041
Кто б сомневался
2009-01-30 16:27
2009.03.29
Функции сравнения строк, почему не так?


15-1233223249
desc
2009-01-29 13:00
2009.03.29
Как обновить набор данных ?





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