![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Вставка записей в 2 таблицы [D5, MSSQL, ]
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:
Спасибо, постараюсь проверить в течение ближайшего времени...