Форум: "Прочее";
Текущий архив: 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
endobject 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