Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Вставка записей в 2 таблицы [D5, MSSQL, ]


Страницы:   1 2 3

Shoo ©   (2001-12-13 13:20:00) 

Мастера, интересует такая вещь: имею БД на MS SQL 7.0, использую ADO, имеется 2 таблицы, KatNakl и SpNakl, связанные таким образом: SpNakl.cNakl -> KatNakl.NRec. По нажатию кнопки хочу добавить данные в обе таблицы, у TADOQuery использую свойство SQL для формирования запроса на добавление и метод ExecSQL для выполнения запроса, примерно так:

procedure TForm1.Button1Click(Sender: TObject);
var mycNakl: longint;
begin
mycNakl := 0;
ADOQuery1.SQL.Clear;
with ADOQuery1.SQL do
begin
Add("insert into katnakl (datenakl, smena, priznak)");
Add("values (""10.12.2001"", 1, ""1"")");
end;
ADOQuery1.ExecSQL;

//как здесь получить новое значение поля NRec в KatNakl,
//записав его, скажем в mycNakl,
//чтобы подставить его в cNakl таблицы SpNakl?

ADOQuery1.SQL.Clear;
with ADOQuery1.SQL do
begin
Add("insert into spnakl (cnakl, name)");
Add("values (" + IntToStr(mycNakl) + ", ""QQQQQQQ""");
end;
ADOQuery1.ExecSQL;
end;
end;

И вообще, правильным ли путем я иду? Как лучше вставлять данные в моем случае? Заранее благодарен.


NewComer   (2001-12-13 16:40:00) [21]

to NeXt:
не должен null быть занят каким то смыслом, null он и в Африке null.
Ну а если уж занят, то {00000000-0000-0000-0000-000000000000} вот тебе и обнуленный идентификатор.


Delirium   (2001-12-13 16:36:00) [22]

Хм, а в какой ситуации идентификатор вообще может содежать значения типа Null или просто 0 ? Это уже не идентификатор а просто поле с цифрами получается :)


neXt   (2001-12-13 16:27:00) [23]

причем null , допустим уже занят каким-то смыслом


neXt   (2001-12-13 16:26:00) [24]

и ещё если уж есть поля с каким-то типом то значит в процедурах будут применятся переменные с этимже типом, а как GUID"ом заменить выражение
exec Procedure_
@ID = @ID out
if @ID = 0
begin
--- то-то и то-то
end


Delirium   (2001-12-13 16:25:00) [25]

"не привычно" - возможно, "не удобно" - предрассудки


neXt   (2001-12-13 16:23:00) [26]

не ну последовательность заполнения таблицы


neXt   (2001-12-13 16:21:00) [27]

ЧЕСНО ГОВОРЯ У меня не 100 процентных аргументов против uniqueidentifier только вот работать с ним не привычно и не удобно


Delirium   (2001-12-13 16:21:00) [28]

"GUID нельзя сравнивать" ты имеешь в виду сортировку?
А с какой стати сортировка должна сториться по идентификаторам?
Операции с идентификаторами "=" и "<>" больше и не надо, это вредно!


NewComer   (2001-12-13 16:19:00) [29]

А при чем тут сравнение идентификаторов?
первичные ключи не должны обладать такой функциональностью.
Я конечно сомневаю в эффективности индексов по ним .. но все же.
Делать то кластерный индекс по ним тебя никто не заставляет.


neXt   (2001-12-13 16:11:00) [30]

GUID нельзя сравнивать , даже произносить в слух не рекомендуется
что касается индексирования полей uniqueidentifier то это тоже самое что и bigint преимуществ никаких (ещё бы они не индексировались они же для ID придуманы!)


Delirium   (2001-12-13 15:58:00) [31]

"GUID не поддерживается некоторыми SQL - платформами" - Shoo - же работает с MSSQL :)


Delirium   (2001-12-13 15:50:00) [32]

"закрытые диапазоны идентифокаторов" А часто-ли это надо? Если и надо, то лучше создать дополнительное поле с псевдоидентификатором, а опираться всё равно на GUID. Если для каждой пары (тройки) таблиц присать свою процедуру - вероятность ошибки вырастает! Кроме того - как быть с удалёнными серверами? - придётся создавать глобальные хранилища идентификаторов, создавать систему рассылки и т.п. А GUID-метод, не мене "работающий" но гораздо более удобный, да и индексация по uniqueidentifier в MSSQL оптимизирована.


neXt   (2001-12-13 15:47:00) [33]

кроме того GUID не поддерживается некоторыми SQL - платформами , для меня это существенное ограничение


neXt   (2001-12-13 15:41:00) [34]

кстати GUID многого не позволяет
например (это не относится к данному случаю) при использовании IDENTITY или его заменителя как в том решении что выше, есть возможность использовать "маленькие ID-шники" закрытые диапазоны идентифокаторов , например для дистрибутивных данных


neXt   (2001-12-13 15:36:00) [35]

устаревший , но работающий


neXt   (2001-12-13 15:35:00) [36]

В Query.SQL пишем
------------------------------------------------
declare @KatNakl_NRec numeric,
@SpNakl_NRec numeric,
@RetVal int

exec @RetVal = KatNakl_SpNakl_Insert
@KatNakl_NRec = @KatNakl_NRec ,
@SpNakl_NRec = @SpNakl_NRec ,
@DateNakl = :DateNakl ,
@Smena = :Smena ,
@Priznak = :Priznak ,
@BarCod = :BarCod ,
@Name = :Name ,
@Kol = :Kol

select @KatNakl_NRec As KatNakl_NRec_NewID,
@SpNakl_NRec As SpNakl_NRec_NewID ,
@RetVal As ErrorCode
-----------------------------------------------
Нужно ещё добавить в Query.Fields три поля поля:
KatNakl_NRec_NewID
SpNakl_NRec_NewID
ErrorCode
,а в окошечке свойства Query.Params появятся все параметры указанные с двоеточием в первом символе (см Query.SQL)
а именно
:DateNakl
:Smena
:Priznak
:BarCod
:Name
:Kol
у каждого из них нужно выстовить (обязательно) свойство DataType
--------------------------------------------------------
это почти всё, НО
нужно ещё передать из кода Delphi значения параметров чтобы произошло добавление записей
это делается так
когда нужно добавить запись выполняется следующий код
///////////////
Query.Params[0].AsDataTime := (*DateNakl - значение*);
Query.Params[1].AsInteger := (*Smena - значение*);
Query.Params[2].AsString := (*Priznak - значение*);
Query.Params[3].AsFloat := (*BarCod - значение*);
Query.Params[4].AsString := (*Name- значение*);
Query.Params[5].AsFloat := (*Kol - значение*);
Query.Open;
/////////////////////
далее можно проверить добавилась ли запись взглянув в поле
Query.FieldByName("ErrorCode").AsInteger
если там 0 - всё окей если нет то надо думать
идентификаторы добавленных записей доступны соответственно из полей
Query.FieldByName("KatNakl_NRec_NewID").AsInteger
Query.FieldByName("SpNakl_NRec_NewID").AsInteger
если надо


Delirium   (2001-12-13 15:25:00) [37]

Согласен с NewComer, то, что предлагает neXt - в общем-то устаревший подход, а GUID - решает кучу проблем.


NewComer   (2001-12-13 15:21:00) [38]

вот я подумал.....
использование identity влечет за собой проблеммы подобного рода.
по-моему все ж лучше использовать в качестве идентификаторов GUID и получать их функцией NewID, будешь знать значение идентификатора перед вставкой. Тут NexT написал целую процедуру (и не лень было ? :-) ), я предлагаю в ней поставить уровень изоляции для транзакции SERIALIZABLE, чтобы небыло накладок при повторном селекте из первой таблицы.


Shoo   (2001-12-13 15:15:00) [39]

Да, кстати, как вызвать-то? А в ADO, действительно, все будет аналогично.


Shoo   (2001-12-13 15:14:00) [40]

2neXt:
Спасибо, постараюсь проверить в течение ближайшего времени...


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо