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

Вниз

Как узнать id добавленной записи в БД?   Найти похожие ветки 

 
И. Павел ©   (2011-03-30 11:48) [0]

Здравствуйте.

Моя программа работает с БД MS SQL Server. Программу одновременно используют несколько пользователей.

Есть 2 таблицы (на самом деле таблиц больше и они сложнее, это просто для примера):

MainTab
id – автоинкрементное поле
data – какие – то данные


SecondTab
id – автоинкрементное поле
IDMainTab – вторичный ключ. Главная таблица – MainTab. Т.е. мне нужно связать эту запись с записью в MainTab.


Когда пользователь нажмет некоторую кнопку, сначала в таблице MainTab создается запись, а потом запись создается в таблице SecondTab, причем последней в поле IDMainTab нужно назначить id только что созданной записи из MainTab.

Подскажите, пожалуйста, как можно решить такую задачу. То есть как мне узнать id записи, созданной в таблице MainTab? Если использовать “SELECT max(id) FROM MainTab”, то можно нарваться на запись, которая создалась после моей...

PS: есть второй вариант организации моей БД: не использовать таблицу MainTab. Но тогда должны быть таблицы SecondTab1, SecondTab2, и т.д., разделяющие общий автоинкрементный индекс. Подскажите, пожалуйста, можно ли так сделать?

Заранее спасибо.


 
clickmaker ©   (2011-03-30 11:51) [1]

> сначала в таблице MainTab создается запись, а потом запись
> создается в таблице SecondTab, причем последней в поле IDMainTab
> нужно назначить id только что созданной записи из MainTab

insert что-то в MainTab
select @id = scope_identity()

insert @id и что-то еще в SecondTab


 
turbouser ©   (2011-03-30 11:52) [2]

SCOPE_IDENTITY
IDENT_CURRENT
+F1


 
И. Павел ©   (2011-03-30 12:22) [3]

clickmaker ©, turbouser ©
Большое спасибо!

Только не понятно, почему не работает код вида:

 ADOC.CommandText := "INSERT INTO BufList (data) VALUES (1);";
 TryToExec(ADOC);

 ADODS.CommandText := "SELECT @@IDENTITY AS si;"; //или ADODS.CommandText := "SELECT SCOPE_IDENTITY() AS si;";
 TryToOpen(ADODS);
 Edit10.Text := ADODS.FieldByName("si").AsString;


Ведь сеанс-то один и тот же (keep connection = true).

Хотя, можно просто написать хранимую процедуру/функцию (или использовать крамольную ADOQuery :).


 
И. Павел ©   (2011-03-30 12:23) [4]

TryToExec/TryToOpen - это просто выполнение запроса, обернутое в try/except для анализа ошибок.


 
Плохиш ©   (2011-03-30 12:26) [5]

Транзакции разные.

PS. Мелкий софт это всë закрыл от простого смертного в LINQ :-)


 
И. Павел ©   (2011-03-30 12:49) [6]

> [5] Плохиш ©   (30.03.11 12:26)

Ясно. Спасибо. Тогда напишу хранимую процедуру.


 
DiamondShark ©   (2011-03-30 13:07) [7]


> Только не понятно, почему не работает код вида:

За слова "не работает код" пора начать убивать.

Как не работает?
Исключение? Класс/сообщение исключения.
Неожиданное поведение? Что хотели. Что получили.


> Ведь сеанс-то один и тот же (keep connection = true).

Значит микрософт наврал в документации. А тебе наслово мы должны верить больше, чем микрософту.

Где код инициализации компонентов?


 
И. Павел ©   (2011-03-30 13:32) [8]


> Неожиданное поведение? Что хотели. Что получили.

Так ведь в [5] все уже объяснили.

> Где код инициализации компонентов?

Там все по умолчанию, кроме Login Prompt:

object ADOConnection1: TADOConnection
   ConnectionString = "Provider=SQLOLEDB.1"
   LoginPrompt = False
   Provider = "SQLOLEDB.1"
   Left = 32
   Top = 16
 end


 object ADOC: TADOCommand
   Connection = DataMod.ADOConnection1
   Parameters = <>
   Left = 64
   Top = 24
 end
 object ADODS: TADODataSet
   Connection = DataMod.ADOConnection1
   Parameters = <>
   Left = 24
   Top = 24
 end


Строка подключения: "Password="+Password.Text+";Persist Security Info=True;User ID="+Login.Text+";Initial Catalog=...;Data Source=...";


 
sniknik ©   (2011-03-30 13:48) [9]

> Только не понятно, почему не работает код вида:
ADOC.CommandText := "INSERT INTO BufList (data) VALUES (1);"#13#10+
                               "SELECT @@IDENTITY AS si;";
TryToOpen(ADOC);

p.s.  странная конструкция, TryToOpen? для одного вызова опен.


 
clickmaker ©   (2011-03-30 13:51) [10]

> странная конструкция, TryToOpen? для одного вызова опен

ну может, там что-то типа
for i:=0 to 1000 do begin
 try
   ADOC.Open;
   break;
 except
   Sleep(1000);
 end;
end;


 
И. Павел ©   (2011-03-30 14:21) [11]

> странная конструкция

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

procedure TryToOpen(DS:TADODataSet; err:string="Во время выборки из базы данных произошла ошибка.");
Begin
 try
   DS.Open;
 except
   on e : exception do DBMessageOut(err+" "+E.Message, DS.CommandText);
 end;
end;


 
И. Павел ©   (2011-03-30 14:35) [12]

> ADOC.CommandText := "INSERT INTO BufList (data) VALUES (1)
> ;"#13#10+
>                               "SELECT @@IDENTITY AS si;
> ";

Спасибо.


 
Игорь Шевченко ©   (2011-03-30 14:41) [13]


>  on e : exception


читать http://delphikingdom.com/asp/viewitem.asp?catalogid=1392


 
Плохиш ©   (2011-03-30 16:45) [14]


> И. Павел ©   (30.03.11 12:49) [6]
>
> > [5] Плохиш ©   (30.03.11 12:26)
>
> Ясно. Спасибо. Тогда напишу хранимую процедуру.

Нафига.

insert into {0} ({1}) output inserted.{2} values({3})

вместо {2} подставляется имя ключевого поля.


 
OW ©   (2011-03-30 17:06) [15]


> Плохиш ©   (30.03.11 16:45) [14]

не, надо хп
надо от табличного подхода уходить в сторону абстракции


 
И. Павел ©   (2011-03-31 08:37) [16]

> [14] Плохиш ©   (30.03.11 16:45)

Потрясающе! Огромное вам спасибо! Я ищу какие-то изощренные способы, а все, оказывается, отлично поддерживается обычным синтаксисом самого запроса insert!


 
DiamondShark ©   (2011-03-31 11:33) [17]


> И. Павел ©   (31.03.11 08:37) [16]

Только начиная с версии 2005


 
И. Павел ©   (2011-03-31 12:52) [18]

> Только начиная с версии 2005

У нас как раз сейчас 2005 стоят.



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

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

Наверх





Память: 0.49 MB
Время: 0.004 c
2-1302078988
parasolka
2011-04-06 12:36
2011.07.17
Запись элементов в динамический массив.


15-1301662532
DVM
2011-04-01 16:55
2011.07.17
Ограничение на число подключений не серверных ОС Windows


8-1213608131
Midous
2008-06-16 13:22
2011.07.17
Воспроизведение музыки без ошибок при отсутствии кодеков


15-1301938826
vrem
2011-04-04 21:40
2011.07.17
Уплавнение: То, ради чего стоит поменять процессор и видеокарту


2-1302097423
Mishutka
2011-04-06 17:43
2011.07.17
сделать активной ячейку StringGrid





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