Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Firebird, Interbase > протоколирование действий пользователей


Автор: TheCetus 28.3.2006, 18:38
Кто сталкивался со следующей задачей: необходимо вести протоколирование действи пользователей. Т.е фиксировать удаление, добавление, модификацию данных и другие действия следующим образом: в определенную табличку на базе записывать имя пользователя производившего действия из системной таблицы users, и данные об операции. Все манипуляции с БД идут через хранимые процедуры, поэтому тип операции определить не сложно.
1. Как определить момент подключения и отключения от БД и зафиксировать его?
2. Как определить имя подключившегося пользователя?
3. Есть еще какие-нибудь предложения по реализации?

Автор: TheCetus 29.3.2006, 13:35
Как в хранимой процедуре на сервере определить имя пользователя вызвавшего процедуру?

Автор: TheCetus 29.3.2006, 14:21
три дня поисков увенчались успехом. Есть контекстная переменная user
имя пользователя можно получить следующим образом:
select user from rdb$database into :puser_name

Автор: TheCetus 30.3.2006, 10:29
Alex, думаю есть резон поместить этот вопрос с фАК

Автор: xgm 30.3.2006, 10:57
Может CURRENT_USER ?

Автор: vv3 12.5.2006, 00:11
Код

CREATE TABLE LOG_ACCESS_TO_BASE(
ACCESS_TIME TIMESTAMP,
USER_NAME VARCHAR(31),
ACCESS_TYPE SMALLINT);


Код

CREATE PROCEDURE LOG$USER(
IACCESSTYPE INTEGER)
AS
BEGIN
        INSERT INTO LOG_ACCESS_TO_BASE(ACCESS_TIME, USER_NAME VARCHAR, ACCESS_TYPE)
         VALUES('NOW', CURRENT_USER, :IACCESSTYPE);
END


Код

//Записываем в лог-таблицу вход
procedure DataModule1.IBDatabase1AfterConnect(Sender: TObject);
begin

//IBSQL1.SQL:= 'EXECUTE PROCEDURE LOG$USER(:IACCESTYPE)'; содержимое TIBSQL

if not IBSQL1.Transaction.Active then IBSQL1.Transaction.StartTransaction;
IBSQL1.Params[0]:= 1; //вход будет 1, выход -1
IBSQL1.ExecQuery;
IBSQL1.Transaction.Commit;
end;

//Записываем выход
procedure DataModule1.IBDatabase1BeforeDisconnect(Sender: TObject);
begin
if not IBSQL1.Transaction.Active then IBSQL1.Transaction.StartTransaction;
IBSQL1.Params[0]:= -1; //вход будет 1, выход -1
IBSQL1.ExecQuery;
IBSQL1.Transaction.Commit;
end;


Что касается вносимых юзером изменений, то я на все интересующие меня таблицы делаю их дубликаты по следующей схеме:

Код

CREATE TABLE ITEM( /*оригинальная таблица*/
ITEM_ID INTEGER NOT NULL,
ITEM_NAME VARCHAR(250),
и т.д.);


Код

CREATE TABLE LOG_ITEM( /*лог-таблица*/
LOG_ITEM_ID INTEGER NOT NULL,
LOG_TIME TIMESTAMP,
LOG_OPERATION CHAR(1), /*I<nsert>, D<elete>, U<pdate>*/
LOG_USER VARCHAR(31), /*виновник торжества - CURRENT_USER*/
OLD_ITEM_ID INTEGER, /*старое значение*/
NEW_ITEM_ID INTEGER, /*новое значение*/
OLD_ITEM_NAME VARCHAR(250),
NEW_ITEM_NAME VARCHAR(250)
и т.д.);

и записываю в нее через триггера AFTER_UPDATE(INSERT, DELETE)
За счет таких таблиц можно даже кое-какие неверные изменения откатить...  

Автор: Akella 15.5.2006, 08:30
У меня по-другому:
сделана таблица пользователей прямо в базе, ну получается так, что все пользователи фактически работают под одним именем, только они об этом не знают. У вот в таблице есть имя пользователя, пароль и код.
Можно сделать отдельную таблицу действий и туда записывать код пользователя, имя таблицы, ID записи и действие. У меня пишется всё через клиентское приложение. 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)