Главная страница
    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
4-1248840141
Armature_Current
2009-07-29 08:02
2011.07.17
Ошибка функции ReadFile при работе с COM-портом


15-1302018111
И. Павел
2011-04-05 19:41
2011.07.17
Ищу роман С. Кинга "Под куполом"


3-1261473731
Xmen
2009-12-22 12:22
2011.07.17
Экспорт базы MySQL в FiriBird


1-1260163351
zsv
2009-12-07 08:22
2011.07.17
Проблемы с минимизацией


2-1302263393
aldis
2011-04-08 15:49
2011.07.17
Listview, подскажите как сварганить





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