-
Здравствуйте, уважаемые мастера Delphi. Прошу, не откажите в помощи..Существует некое рабочее место АРМ, например мастера, куда в табличной форме (DBGrid) выводятся данные по различным объектам (написано это АРМ на Delphi). В таблице мастер может данные редактировать, удалять, вносить новые строки заполняя их данными (при этом может сохранить введенные данные, а может и не сохранять). и вот требуется на этом рабочем месте дописать действия BeforeEdit, AfterInsert, чтобы и те данные которые были+новые+ фамилия того, кто изменения делал - записались в таблицу аудит. у меня скоро мозг взорвется.
Код для того, чтобы старые данные переносились в другую таблицу до начала редактирования (BeforeEdit) , следующий: Код Delphi
DataModule2.DataSet_material_audit.Close; DataModule2.DataSet_material_audit.DeleteVariables; DataModule2.DataSet_material_audit.SQL.Clear; DataModule2.DataSet_material_audit.SQL.Add('begin'); DataModule2.DataSet_material_audit.SQL.Add('insert into develop.materials_audit(smelt_ident, number_processing, stage, material_kind, in_number,material_old, weight_old, event_time, material_new, weight_new, type_oper, familia) '); DataModule2.DataSet_material_audit.SQL.Add('values(:smI, :npr, :stg, ''1'', NVL((select max(in_number) from develop.materials_audit where smelt_ident=:smI), 0)+1,:mtrl_old,:wes_old, sysdate, null, null, ''2'', :fml);'); DataModule2.DataSet_material_audit.SQL.Add('commit;'); DataModule2.DataSet_material_audit.SQL.Add('end;'); DataModule2.DataSet_material_audit.DeclareVariable('smI', otInteger); DataModule2.DataSet_material_audit.SetVariable('smI', Smelt.SmI); DataModule2.DataSet_material_audit.DeclareVariable('npr', otInteger); DataModule2.DataSet_material_audit.SetVariable('npr', 1); DataModule2.DataSet_material_audit.DeclareVariable('stg', otString); DataModule2.DataSet_material_audit.SetVariable('stg', Smelt.Stage); DataModule2.DataSet_material_audit.DeclareVariable('mtrl_old', otString); DataModule2.DataSet_material_audit.SetVariable('mtrl_old', DataModule2.DataSet_ferr.FieldByName('Additional_Name').AsString); DataModule2.DataSet_material_audit.DeclareVariable('wes_old', otInteger); DataModule2.DataSet_material_audit.SetVariable('wes_old', DataModule2.DataSet_ferr.FieldByName('AMOUNT').AsInteger); DataModule2.DataSet_material_audit.DeclareVariable('fml', otString); DataModule2.DataSet_material_audit.SetVariable('fml', Curr_user.Familia); DataModule2.DataSet_material_audit.Open;
а как дальше сделать, что-то не соображу..может через динамический массив, где от типа действия (редактирование, удаление, добавление новой строки, сохранение) данные либо записываются в таблицу, либо затираются в памяти..как оформить не знаю..опыта еще мало..
-
пора написать сверху на странице форума, Если вопрос по БД - указывайте СУБД
-
> [1] [ВладОшин] © (15.05.14 09:50) > указывайте СУБД
БД одна - TTable. Либо SQL сервер.
> [0] Natalinrf (14.05.14 14:39)
Судя по контексту, в БД могут быть триггеры. В них и сделать.
-
похоже на oracle но я совсем никак в фб. может это оно.. все же, надо указавать субд
И все же не триггер, а хранимку. 1. триггер можно забыть учитывать потом 2. Стимулирует табличный подход
-
>[ВладОшин] © (15.05.14 10:42) [3] sysdate, nvl - точно Oracle
а автору, действительно, надо курить триггеры, чтобы не записывать(при этом через анонимный блок - зачем?) несуществующие данные в аудит
-
а вообще смысл? переносить/синхронизировать данные во вторую таблицу если их же легко можно взять из первой ... ???
-
База данных Oracl. Доступ осуществляется по компоненту Direct Oracle Access 4.0.7.1..
-
Триггеры на базу не написать, так как доступ к базе закрыт(нет прав), можно писать только запросы к ней..
-
>Natalinka © (15.05.14 12:32) [7] 1. кто создал таблицу аудита develop.materials_audit? 2. что будет в in_number, если два пользователя одновременно выполнят insert? 3. Зачем логировать то, что никогда не будет записано в базу?
-
Кщд (15.05.14 12:45) [8] 1. Таблицу создал руководитель, 2. in_number - это поле по порядку (в принципе оно не важно) 3. так желает его величество руководитель..в общем-то тут еще с ним можно поспорить.
-
>Natalinka © (15.05.14 13:02) [9] 1. доступ к схеме develop у вас есть? 2. в данном случае, никаким "по порядку" и не пахнет, увы 3. т.е. "руководитель" хочет, чтоб при попытке редактирования записи, её текущее состояние записывалось в лог? даже, если это редактирование НЕ БУДЕТ подтверждено(commit) в базе?
-
Кщд (15.05.14 13:10) [10] 1.нет у меня еще ни какого доступа. 3. именно так. он хочет видеть кто залазил в базу и какие изменения пытался внести.
-
аля
for i := 0 to DataSet.FieldCount - 1 do begin DataSetInsert.Parameters.Items[i].Value := DataSet.Fields[0].OldValue; DataSetInsert.ExecSql;
DataSetInsert.Parameters.Items[i].Value := DataSet.Fields[0].NewValue; DataSetInsert.ExecSql; end;
только в DOA по моему DataSetInsert.Params.Items[i].Value :=
-
> DataSetInsert.ExecSql;
вынести за цикл Ж)
-
>Natalinka © (15.05.14 13:15) [11] >1.нет у меня еще ни какого доступа. если вставляете данные, значит, есть
>3. именно так. он хочет видеть кто залазил в базу и какие изменения пытался внести. думаю, Вы неверно поняли руководителя
-
Кщд (15.05.14 14:16) [14] >3. именно так. он хочет видеть кто залазил в базу и какие изменения пытался внести. думаю, Вы неверно поняли руководителя - в том-то и дело, что верно поняла...я просто не буду этот вариант прописывать.. в общем вот, что у меня получилось вариант когда пользователь добавляет строку, вносит данные и сохраняет их, нажимая кнопку "Сохранить" объявление массива public Str_SQL: array of AnsiString;
обработчики событий procedure TDataModule2.DataSet_ferrBeforeEdit(DataSet: TDataSet); begin try // íà ñëó÷àé îøèáêè ïðîïèñûâàåì öèêë try...except DataModule2.DataSet_material_audit.Close; DataModule2.DataSet_material_audit.DeleteVariables; DataModule2.DataSet_material_audit.SQL.Clear; DataModule2.DataSet_material_audit.SQL.Add('begin'); DataModule2.DataSet_material_audit.SQL.Add('insert into develop.materials_audit(smelt_ident, number_processing, stage, material_kind, in_number,material_old, weight_old, event_time, material_new, weight_new, type_oper, familia) '); DataModule2.DataSet_material_audit.SQL.Add('values(:smI, :npr, :stg, ''1'', NVL((select max(in_number) from develop.materials_audit where smelt_ident=:smI), 0)+1,:mtrl_old,:wes_old, sysdate, null, null, ''2'', :fml);'); DataModule2.DataSet_material_audit.SQL.Add('commit;'); DataModule2.DataSet_material_audit.SQL.Add('end;'); DataModule2.DataSet_material_audit.DeclareVariable('smI', otInteger); DataModule2.DataSet_material_audit.SetVariable('smI', Smelt.SmI); DataModule2.DataSet_material_audit.DeclareVariable('npr', otInteger); DataModule2.DataSet_material_audit.SetVariable('npr', 1); DataModule2.DataSet_material_audit.DeclareVariable('stg', otString); DataModule2.DataSet_material_audit.SetVariable('stg', Smelt.Stage); DataModule2.DataSet_material_audit.DeclareVariable('mtrl_old', otString); DataModule2.DataSet_material_audit.SetVariable('mtrl_old', DataModule2.DataSet_ferr.FieldByName('Additional_Name').AsString); DataModule2.DataSet_material_audit.DeclareVariable('wes_old', otInteger); DataModule2.DataSet_material_audit.SetVariable('wes_old', DataModule2.DataSet_ferr.FieldByName('AMOUNT').AsInteger); DataModule2.DataSet_material_audit.DeclareVariable('fml', otString); DataModule2.DataSet_material_audit.SetVariable('fml', Curr_user.Familia); DataModule2.DataSet_material_audit.Open; except on E: Exception do begin ShowMessage('Ошибка :'+E.Message); end; end; ShowMessage('Все отработало');// потом это сообщение уберу
end;
procedure TDataModule2.DataSet_ferrAfterInsert(DataSet: TDataSet); var
St: Integer; // строка
begin DataModule2.DataSet_material_audit.Close; DataModule2.DataSet_material_audit.DeleteVariables; DataModule2.DataSet_material_audit.SQL.Clear; St:=length(Smelt.Str_SQL); Setlength(Smelt.Str_SQL,length(Smelt.Str_SQL)+1); Smelt.Str_SQL[St]:='insert into develop.materials_audit(smelt_ident, number_processing, stage, material_kind, in_number,material_old, weight_old, event_time, material_new, weight_new, type_oper, familia) '; St:=length(Smelt.Str_SQL); Setlength(Smelt.Str_SQL,length(Smelt.Str_SQL)+1); Smelt.Str_SQL[St]:='values('+IntToStr(Smelt.SmI)+',1, '''+Smelt.Stage+''', ''1'', NVL((select max(in_number) from develop.materials_audit where smelt_ident='+IntToStr(Smelt.SmI)+'), 0)+1, NULL, NULL, sysdate, '''+ DataSet_ferr.FieldByName('additional_name').AsString+''', '+DataSet_ferr.FieldByName('amount').AsString+', ''0'', '+char(30)+Curr_user.Familia+char(30)+');'; end; на кнопке "Сохранить " массив save_all_data(true);
for i:=0 to length(Smelt.Str_SQL)-1 do begin DataModule2.DataSet_material_audit.SQl.ADD(Smelt.Str_SQL[i]); end;
for i:=0 to length(Smelt.Str_SQL)-1 do begin Smelt.Str_SQL[i]:=''; end; Setlength(Smelt.Str_SQL, 0);
Smelt.my_search(); N4Click(nil); Беда в том, что копируются данные всей таблицы...
-
как затереть данные, которые уже были записаны в таблицу, а пользователь решил не сохранять изменения?
-
>Natalinka © (15.05.14 14:38) [16] 1. где затереть? 2. зачем вы используете анонимный pl/sql-блок для записи данных? 3. почему вы используете чудовищную и некорректную конструкцию: select max(in_number)...?
-
> как затереть данные, которые уже были записаны в таблицу, > а пользователь решил не сохранять изменения?
Их просто не нужно писать в лог до того, как пользователь подтвердит изменения. Вместо BeforePost обрабатывайте AfterPost
-
Кщд (15.05.14 15:22) [17] 2. зачем вы используете анонимный pl/sql-блок для записи данных? - Что значит анонимный? 3. почему вы используете чудовищную и некорректную конструкцию: select max(in_number)...? - а как нужно? у меня опыт равен нулю практически в базах данных
|