Як дізнатися id доданого запису в БД
Моя програма працює з БД 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 і т.д., що розділяють загальний автоінкрементний індекс. Підкажіть, будь ласка, чи можна це зробити?
> спочатку у таблиці MainTab створюється запис, та був запис > створюється у таблиці SecondTab, причому останньої у полі IDMainTab > потрібно призначити id щойно створеного запису з MainTabinsert щось у MainTab select @ > insert @id і щось ще в SecondTab
Тільки не зрозуміло, чому не працює код виду:
ADOC.CommandText := "INSERT INTO BufList (data) VALUES (1);"; TryToExec(ADOC);
ADODS.CommandText := "SELECT @@ ; TryToOpen(ADODS); Edit10.Text := ADODS.FieldByName("si").AsString;
Адже сеанс-то той самий (keep connection = true).
Хоча, можна простонаписати процедуру/функцію, що зберігається (або використовувати крамольну ADOQuery :).
TryToExec/TryToOpen – це просто виконання запиту, обернене у try/except для аналізу помилок.
PS. Дрібний софт це все закрив від простого смертного в LINQ :-)
> Тільки не зрозуміло, чому не працює код виду:За слова "не працює код" настав час почати вбивати.
Як не працює? Виняток? Клас/повідомлення винятку. Несподівана поведінка? Що хотіли. Що здобули.
> Адже сеанс-то один і той же (keep connection = true). Значить мікрософт набрехав у документації. А тобі на слово ми маємо вірити більше, ніж мікрософту.
Де код ініціалізації компонентів?
> Несподівана поведінка? Що хотіли. Що отримали.Так адже в [5] все вже пояснили.
> Де код ініціалізації компонентів?Там все за замовчуванням, крім Login Prompt:
object ADOConnection1: TADOConnection ConnectionString = "Prov > LoginPrompt = False Prov 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 ;
> Тільки не зрозуміло, чому не працює код виду: ADOC.CommandText := "INSERT INTO BufList (data) VALUES (1);"#13#10+ "SELECT @@IDENTITY AS si;"; TryToOpen(ADOC);
p.s. дивна конструкція, TryToOpen? для одного дзвінка опен.
> дивна конструкція, TryToOpen? для одного виклику опенну може там щось типу for i:=0 to 1000 do begin try ADOC.Open; break; except Sleep(1000); end; end;
> дивна конструкціяПросто у мене при помилках запитів виводиться спеціальне вікно (DBMessageout(. )), в якому є текст і сам запит (зручно при налагодженні і якщо помилка виникла в динамічно згенерованому запиті). Ну і ще можна вказати текст помилки свій.
procedure TryToOpen(DS:TADODataSet; err:string="Під час вибірки з бази даних сталася помилка."); Begin try DS.Open; except on e : exception до DBMessageOut(err+" "+E.Message, DS.CommandText); end; end;
> ADOC.CommandText := "INSERT INTO BufList (data) VALUES (1) > ;"#13#10+ > "SELECT @@IDENTITY AS si; > ";Дякую.
> Тільки з версії 2005У нас якраз зараз 2005 стоять.