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

Вниз

Как узнать 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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.01 c
15-1301644671
sniknik
2011-04-01 11:57
2011.07.17
Pivot tables in OpenOffice Calc ... формирование программно


15-1301572664
vajo
2011-03-31 15:57
2011.07.17
Мозилла


15-1301936177
Leon-Z
2011-04-04 20:56
2011.07.17
БД в формате XML ???


2-1302088974
ddd329
2011-04-06 15:22
2011.07.17
Заголовок в Indy корявый


1-1260357382
ther
2009-12-09 14:16
2011.07.17
TChart и табличка вверху