Форум: "Базы";
Текущий архив: 2003.09.01;
Скачать: [xml.tar.bz2];
ВнизКак сделать Refresh для одной записи ClientDataSet Найти похожие ветки
← →
OlkaGTS (2003-08-07 13:49) [0]Уважаемые!
Есть трехуровневое приложение. На клиенте ClientDataset получается joinом из нескольких таблиц. В приложении-сервере у DataSetProvider в BeforeUpdateRecord вызывается хр пр, которая это все сохраняет. Но после всего этого я не вижу поле типа identity на клиенте, а делать Refresh всему dataset не хочется, потому что изменения на сервере должны сохраняться после каждого post. Можно ли каким-то другим способом получить значение этого поля?
← →
clickmaker (2003-08-07 13:58) [1]Попробуй RefreshRecord
← →
OlkaGTS (2003-08-07 14:00) [2]RefreshRecord не получается по той же причине. Нет первичного ключа, по которому он мог бы его сделать
← →
Nikolay M. (2003-08-07 14:04) [3]БД какая?
В IB делалось так: создавалась хранимая процедура, которая при каждом вызове возвращала автоинкрементное значение генератора (можно и просто табличку для этого завести) и которое потом уже использовалось во всяких
INSERT INTO table (ID, ...) VALUES (:ID, ...)
и тп.
Очень удобно, когда редактируется одна из нескольких связанных таблиц.
← →
OlkaGTS (2003-08-07 14:06) [4]БД MSSQL. Там не генераторов
← →
Nikolay M. (2003-08-07 14:30) [5]Тогда можно завести таблицу CREATE TABLE (id_value INTEGER, table_name VARCHAR(255)) и сваять под нее маленькую процедурку, которая по имени таблицы будет возвращать каждый раз автоинкреметное id_value.
Кстати, раз уж у тебя трехзвенка, то можно вообще ID на уровне RemoteDataModule генерировать :) Только не забыть генерацию в критической секции делать - многопоточность все-таки. Ну или любой другой способ синхронизации потоков, какой больше нравится.
← →
OlkaGTS (2003-08-07 14:37) [6]Проблема не в этом. Значение поля генерирует сам сервер, но после сохранения я не вижу это значение на клиенте, пока не сделаю Dataset.Refresh. При этом обновятся все записи, а мне нужно только одна конкретная, которую только что вставили.
У провайдера в options есть poAutoRefresh и poPropagateChanges, которые вроде бы должны это делать. Но они этого почему-то не делают
← →
Nikolay M. (2003-08-07 14:53) [7]Как раз проблема именно в этом. Кто тебе сказал, что после INSERT провайдер будет сразу делать SELECT только что вставленной записи? И опции тут не помогут. А если будешь делать одним из методов, как я сказал в
> Nikolay M. © (07.08.03 14:30)
, тогда и проблемы не будет. Для MS SQL можно рискнуть вытянуть @@IDENTITY или как она там зовется, не помню точно - ID последней вставленной записи, но есть вероятность нарваться...
Короче, мой совет - вставлять запись с уже известным на уровне провайдера ID. Вот тогда poAutoRefresh и poPropagateChanges вернут это значение назад на клиент. Но от БД на провайдер значения придут только после Refresh-а.
← →
OlkaGTS (2003-08-07 16:53) [8]Я не могу изобретать никакие новые методы. База должна работать по классической технологии. Отсюда следует, что вытягивание @@Identity ничего не дает, поскольку я его потом никуда не могу записать, так как автоинкрементные поля Read Only.
Т.е. насколько я понимаю, получить ID только что вставленной записи невозможно никак, кроме как Refresh всему DataSet?
← →
Nikolay M. (2003-08-07 17:15) [9]
> Отсюда следует, что вытягивание @@Identity ничего не дает,
> поскольку я его потом никуда не могу записать, так как автоинкрементные
> поля Read Only.
SET IDENTITY_INSERT MyTable ON
еще никто не отменял.
> получить ID только что вставленной записи невозможно никак,
> кроме как Refresh всему DataSet?
В таблице есть еще первичные ключи? Скажем, уникальное название или еще что-то... По нему можно вытянуть ID.
> База должна работать по классической технологии.
Диплом???!
← →
OlkaGTS (2003-08-07 17:27) [10]CREATE TABLE TT ([ID] int identity(1,1) PRIMARY KEY и т.д.) - этот первичный ключ и имелся ввиду.
А по классической технологии в том смысле, что все первичные ключи - это поля identity и никак иначе и генерироваться значения должны сервером, поскольку с базой работает не одно приложение
← →
Nikolay M. (2003-08-07 17:59) [11]Ну и создай хранимую процедуру, которая эти PRIMARY KEY будет тягать из таблицы. Только блокировку на уровне записи не забыть наложить. И чем это не генерация ID на уровне БД?
Нет, ну если очень хочется, тогда
CDS.Active := False;
CDS.Active := True;...
Пользователи спасибо скажут :)
← →
Polevi (2003-08-07 18:29) [12]procedure TRDM.BeforeUpdateRecord_(Sender: TObject; SourceDS: TDataSet;
DeltaDS: TClientDataSet; UpdateKind: TUpdateKind; var Applied: Boolean);
begin
if UpdateKind=ukInsert then
begin
qry:=TADOQuery.Create(nil);
try
qry.Connection:=SomeAdoConnection;
qry.SQL.Add("EXEC bla-bla-bla);
qry.SQL.Add("SELECT @@IDENTITY");
qry.Open;
DeltaDS.FieldByName("ID").ReadOnly:=false;
( "ID") procedure TRDM.BeforeUpdateRecord_(Sender: TObject; SourceDS: TDataSet;
DeltaDS: TClientDataSet; UpdateKind: TUpdateKind; var Applied: Boolean);
begin
if UpdateKind=ukInsert then
begin
qry:=TADOQuery.Create(nil);
try
qry.Connection:=SomeAdoConnection;
qry.SQL.Add("EXEC bla-bla-bla);
qry.SQL.Add("SELECT @@IDENTITY");
qry.Open;
DeltaDS.FieldByName("ID").ReadOnly:=false;
DeltaDS.FieldByName("ID").NewValue:=qry.Fields[0].Value;
finally
qry.Free
end;
Applied:=true;
end;
end;
← →
Romkin (2003-08-07 18:57) [13]Опять счетчики... Так надоело...
>А по классической технологии в том смысле, что все первичные ключи - это поля identity и никак иначе
Мдя, что за классика? Явно форма выше НФБК. Насчет получения уникальных значений см http://rsdn.ru/article/db/midas_migration.xml
в частности,
http://rsdn.ru/article/db/midas_migration.xml#XSLTSECTION124143120120
Все описано, все работает.
← →
Polevi (2003-08-07 20:38) [14]2Romkin © (07.08.03 18:57)
например мне нужно выполнить SP на сервере которая сделает INSERT нескольких записей - при таком подходе это будет не просто сделать, если в таблице есть уникальное поле
← →
Nikolay M. (2003-08-07 23:04) [15]
> Насчет получения уникальных значений см http://rsdn.ru/article/db/midas_migration.xml
> в частности,
> http://rsdn.ru/article/db/midas_migration.xml#XSLTSECTION124143120120
Именно это и пытаюсь втолковать, пока не очень получается :(
← →
corte ™ (2003-08-08 07:50) [16]А букмарками не пользовался ?
← →
Polevi (2003-08-08 09:38) [17]2Nikolay M. © (07.08.03 23:04)
есть таблица шапок документов и их содержимого
в таблице содержимого кластерный индекс
напиши мне XP которая сделает копию документа
БД MS SQL сервер
← →
Polevi (2003-08-08 09:39) [18]>напиши мне XP
сорри, SP конечно
← →
Nikolay M. (2003-08-08 10:34) [19]
> Polevi © (07.08.03 20:38)
> например мне нужно выполнить SP на сервере которая сделает
> INSERT нескольких записей - при таком подходе это будет
> не просто сделать, если в таблице есть уникальное поле
А зачем пользоваться этим методом там, где он себя не оправдывает?
> есть таблица шапок документов и их содержимого
> в таблице содержимого кластерный индекс
Таблиц все-таки одна или две?
← →
Polevi (2003-08-08 10:47) [20]2, отношение 1 ко многим
← →
Polevi (2003-08-08 10:51) [21]при твоем способе придется писать курсор
если поле AutoInc все делается одним
INSERT INTO .. SELECT FROM
если стоит задача независимости от БД, тогда всю логику нужно реализовать на middleware, а БД использовать только как набор таблиц и индексов, и никаких SP, ф-ий, курсоров и тд, только SQL 92
если такой задачи нет - незачем отказываться от функциональности СУБД и сочинять велосипеды
← →
Nikolay M. (2003-08-08 11:13) [22]
> при твоем способе
Это совсем не мой способ :)
Хоть я сначала и придумал его, а потом уже только прочитал статью на rsdn.
Можно поизвращаться, искуственно ввести дополнительно временный Primary Key, который будет генерироваться случайным образом из очень широкого диапазона... Но красотой такой вариант не блещет :(
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2003.09.01;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.009 c