2014-10-29 2 views
0

код, как это записывает все вставки таблицы (из всего приложения):Как вы регистрируете конкретную таблицу в Accuracer?

procedure TForm1.ACRDatabase1AfterInsertRecord(Sender: TACRDataSet; 
    const TableName: WideString; const FieldValues: TACRArrayOfTACRVariant); 
begin 
if (AnsiUpperCase(TableName) = AnsiUpperCase(LogTable.TableName)) then 
Exit; 
if (Sender is TACRTable) then 
LogTable.Insert(); 
LogTable.FieldByName('EventTime').AsDateTime := Now; 
LogTable.FieldByName('TableName').AsString := TableName; 
LogTable.FieldByName('EventType').AsString := 'Insert '; 
LogTable.FieldByName('Whatever').AsString := FieldValues[4].AsString; 
LogTable.Post(); 
end; 

Но FieldValues ​​отличаются для каждой таблицы, чтобы вы могли врезаться приложения (почти наверняка), используя FieldValues ​​их число т.е. индекс.

Как вы преодолеваете это? Можно ли записывать каждую таблицу отдельно?

+0

Имеют ли элементы FieldValues ​​свойство тега? Если это так, вы можете установить тег требуемого элемента до вызова AfterInsertRecord, а затем перебрать элементы, которые ищут отмеченный. –

+0

TACRArrayOfTACRVariant специфичен для Accuracer, которого у меня нет. Однако, если вы знаете поле (ы), которое вы хотите регистрировать для определенных таблиц, вам может быть проще выполнить регистрацию в таблицах «Событие AfterInsert». Нужно больше объяснений? – MartynA

+0

@ No'am Newman - да, поля имеют свойство тега, но я не знаю, как реализовать это. Никогда не делал такую ​​вещь ... – user3927897

ответ

0

Как я уже говорил в комментариях, я не Accuracer, но думал, что это может быть полезно чтобы опубликовать общий метод ведения клиента ведения журнала, который может захватить значение из одного или нескольких полей и быть используется для как можно большего количества наборов данных. Возможно, вы используете , чтобы использовать его часть в обработчике ACRDatabase1AfterInsertRecord, так как появляется его параметр Sender , чтобы идентифицировать набор данных, в который была вставлена ​​новая строка.

Как вы можете видеть, есть процедура LogFields, которая может быть включена в обработчик любого набора данных вы хотите AfterInsert и это требует отдельной процедуры GetFieldsToLog которая добавляет имена поля (ы) для входа для заданный набор данных для временного StringList. Это только процедура GetFieldsToLog, которая должна быть адаптирована к потребностям данного набора наборов данных.

procedure TForm1.GetFieldsToLog(ADataSet : TDataSet; FieldList : TStrings); 
begin 
    FieldList.Clear; 
    if ADataSet = AdoQuery1 then begin 
    FieldList.Add(ADataSet.Fields[0].FieldName); 
    end 
    else 
    // obviously, deal with other specific tables here 
end; 

procedure TForm1.LogFields(ADataSet : TDataSet); 
var 
    TL : TStringList; 
    i : Integer; 
    ValueToLog : String; 
begin 
    TL := TStringList.Create; 
    try 
    GetFieldsToLog(ADataSet, TL); 
    for i := 0 to TL.Count - 1 do begin 
     ValueToLog := ADataSet.FieldByName(TL[i]).AsString; 
     // do your logging here however you want 
    end; 
    finally 
    TL.Free; 
    end; 
end; 

procedure TForm1.ADOQuery1AfterInsert(DataSet: TDataSet); 
begin 
    LogFields(DataSet); 
end; 

Btw, одна из точек, имеющих отдельную процедуру GetFieldsToLog является то, что она помогает продлить на стороне клиента, ведение журнала изменений в существующих наборов данных записей. Если вы создадите этот список при запуске и сохраните его где-нибудь, вы можете использовать его в событии BeforePost набора данных до , чтобы получить текущие и предыдущие значения поля (используя его свойства Value и OldValue), сохранить эти в другом StringList и зарегистрировать их в событии AfterPost. Конечно, , если вы используете общий магазин для этих значений из более чем одного набора данных, вам нужно сделать уверенным, что AfterPost одного набора данных загорится перед BeforePost любого другого или сделайте запись целиком в пределах BeforePost (для хранения старых и текущих значений полей между Pre- и AfterPost является грязным, и было бы лучше сделать все в AfterPost, , но, к сожалению, OldValue устарел до того момента, когда появится AfterPost.

Имейте в виду, что получение OldValue требует, чтобы определенный тип набора данных правильно реализовал . Не все типы данных, которые я натолкнулся, все же нуждаются в проверке.

Btw # 2, предполагая, что у вас есть процедура, как этот

procedure TForm1.DoSomething(AnObject : TObject); 

, то вы можете использовать «, если AnObject это ..."Сделать что-то вроде этого

var 
    AnAdoQuery : TAdoQuery; 
begin 
    if AnObject is TAdoQuery then begin 
    // First, use a cast to assign Sender to the local AnAdoQuery variable 
    AnAdoQuery := TAdoQuery(AnObject); 
    // Then, we can do whatever we like with it, e.g. 
    Caption := AnAdoQuery.Name; 
    end; 
end; 

Ото, если по какой-то причине (и я не могу сразу думать, почему мы хотели бы, но не против) мы просто хотим, чтобы проверить, что то, что мы прошли, как параметр AnObject является частным объект, мы можем опустить бросок и просто сделать

if AnObject = AdoQuery1 then 
    ShowMessage('Received AdoQuery1'); 

Это равенство проверки работы, независимо от фактического класса то, что мы прошли в качестве параметра AnObject, потому что все другие классы являются потомками объявленного класса AnObject , а именно TObj ЭСТ.

+0

не «FieldList.Add (ADataSet.Fields [0] .FieldName);» в основном то же, что «LogTable.FieldByName (« Что бы ни случилось »). AsString: = FieldValues ​​[4] .AsString;" ? – user3927897

+0

Действительно, они, возможно, в основном одно и то же (я говорю «возможно», потому что я не совсем уверен, что ваш «[...]: = FieldValues ​​[4] .AsString [...]» предназначен для этого) , Все, что я пытался сделать, это предложить способ решения вашей проблемы, который был a) общим, то есть не ограничивается Accuracer, или конкретными наборами данных в приложении, b) легко поддерживаемым, поскольку любые необходимые изменения могут быть сконцентрированы в процедура GetFieldsToLog() и c) расширяемость в том смысле, что она легко расширяема для таких вещей, как внесение изменений в значения полей. [cont] – MartynA

+0

... Кстати, я мог видеть из предыдущего вашего вопроса, что вы уже знакомы с триггерами на стороне сервера, поэтому, возможно, они могли бы выполнять ведение журналов на стороне сервера на их основе, если это было бы уместно для кругов, около. – MartynA

Смежные вопросы