Как записать выполненный SQL
Как записать выполненный SQL
Вопрос такой:
Необходимо, чтобы при обновлении (добавлениеии, удалении) записи, запрос, который был выполнен, записывался в txt.
Может в триггерах чего написать.... а чего?
(IB7, Delphi7)
Необходимо, чтобы при обновлении (добавлениеии, удалении) записи, запрос, который был выполнен, записывался в txt.
Может в триггерах чего написать.... а чего?
(IB7, Delphi7)
-
- Сообщения: 6
- Зарегистрирован: 27 окт 2004, 06:35
Re: Как записать выполненный SQL
Ну смотря для чего. Если правильно понял то использовать AfterExecute (и подобные для нужных вещей) в самой программе. И пиши что душе угодно и куда хочешь.Klyk писал(а):Вопрос такой:
Необходимо, чтобы при обновлении (добавлениеии, удалении) записи, запрос, который был выполнен, записывался в txt.
Может в триггерах чего написать.... а чего?
(IB7, Delphi7)
А в триггерах ты ничего не получишь, текста запроса там нет. Хотя можно конечно записывать измененные поля к примеру, но условия в WHERE ты однозначно потеряешь.
P.S. Кстати, данный вариант катит для ФИБов вроде бы только. Для IBX в TIBSQL придется после выполнения запроса писать сброс текста. А вообще непонятная задача какая-то. Зачем это нужно?
Например для логирования действий можно писать во внешнюю таблицу например так:
примерно так реализовать для update, вероятно есть ошибки(для строковых полей нужно еще и кавычки в s_sql засунуть), но ...
Для сохранения в текстовый файл, на сервере можно использовать UDF, которая получает необходимые параметры и сохраняет их в определенную папку, тогда добавление во внешнюю таблицу заменить на:
в fields_count можно передавать код завершения udf.
Можно еще свой монитор написать.
Код: Выделить всё
create trigger au_triggername for tablename after update position 0
as
declare variable s_sql varchar(2000);
declare variable fields_count integer;
begin
s_sql = 'update table name set ';
fields_count = 0;
if (new.field1 <> old.field1) then begin
select :s_sql || ' field1 = ' || cast(new.field1 as varchar(20))
from rdb$database into :s_sql;
fields_count = 1;
end
if (new.field2 <> old.field2) then begin
if (fields_count > 0) then s_sql = s_sql || ',';
select :s_sql || ' field2 = ' || cast(new.field2 as varchar(20))
from rdb$database into :s_sql;
fields_count = fields_count + 1;
end
...
select :s_sql || ' where PKFIELD = ' || cast(old.pkfield as varchar(20))
if (fields_count > 0) then
insert into ext_table(..., fields_changed, sql_type, sql_text) values (..., fields_count, 'update', :s_sql);
end
Для сохранения в текстовый файл, на сервере можно использовать UDF, которая получает необходимые параметры и сохраняет их в определенную папку, тогда добавление во внешнюю таблицу заменить на:
Код: Выделить всё
select udf_save_to_txt_file(..., :s_sql) from rdb$database into :fields_count;
Можно еще свой монитор написать.
Ага. Я с монитором не работал, но что-то подсказывает мне что отследить обновление данных с его помощью немного невозможно, т.к. существуют такие вещи как транзакции и откаты. но если нужно сохранять все запросы которые идут из программы к серверу - то это да, единственный путь наверное (кроме вставки в саму прогу соответствующего кода).Deniz писал(а):Например для логирования действий можно писать во внешнюю таблицу например так
[skiped]
примерно так реализовать для update, вероятно есть ошибки(для строковых полей нужно еще и кавычки в s_sql засунуть), но ...
Можно еще свой монитор написать.
По поводу условий я уже писал, через триггеры мы получим сохранение не _запроса_ (как было спрошено в самом вопросе) а только _данных_, что является не совсем чем чем нужно.
-
- Сообщения: 6
- Зарегистрирован: 27 окт 2004, 06:35
Из первого сообщения Автора:Andrew Kruchinin писал(а): ... что является не совсем чем чем нужно.
хочу обратить внимание на слово записи если Автор уточнит свой вопрос, тогда можно будет говорить о несостоятельности того или иного варианта.Klyk писал(а): ... при обновлении (добавлениеии, удалении) записи ...
На самом деле зачем это всё надо.
Есть 2 БД, связь между которыми - невозможна, следовательно репликатор неподходит. А изменения в одной БД надо отображать в другой. Есть возможность передачи только текстовых файлов (раз в сутки).
Вот я и думал создавать SQL скрипты при изменении данных в одной БД и выполнять этот скритп для изменения второй БД.
Может есть и другие идеи...
Есть 2 БД, связь между которыми - невозможна, следовательно репликатор неподходит. А изменения в одной БД надо отображать в другой. Есть возможность передачи только текстовых файлов (раз в сутки).
Вот я и думал создавать SQL скрипты при изменении данных в одной БД и выполнять этот скритп для изменения второй БД.
Может есть и другие идеи...
-
- Сообщения: 6
- Зарегистрирован: 27 окт 2004, 06:35
Согласен, тем более что более полная цитатаDeniz писал(а):Из первого сообщения Автора:Andrew Kruchinin писал(а): ... что является не совсем чем чем нужно.
хочу обратить внимание на слово записи если Автор уточнит свой вопрос, тогда можно будет говорить о несостоятельности того или иного варианта.Klyk писал(а): ... при обновлении (добавлениеии, удалении) записи ...
вносит полный разбродНеобходимо, чтобы при обновлении (добавлениеии, удалении) записи, запрос, который был выполнен, записывался в txt.

-
- Сообщения: 6
- Зарегистрирован: 27 окт 2004, 06:35
А, ну если так то в принципе ты можешь создавать конечно запросы из самих тригеров. но есть чреватости и подводные камни при таком подходе если что. Особенно если таблицы будут связаны ключами к примеру. Т.е. можно на такие грабли наступить что ой-ой-ой.Klyk писал(а):На самом деле зачем это всё надо.
Есть 2 БД, связь между которыми - невозможна, следовательно репликатор неподходит. А изменения в одной БД надо отображать в другой. Есть возможность передачи только текстовых файлов (раз в сутки).
Вот я и думал создавать SQL скрипты при изменении данных в одной БД и выполнять этот скритп для изменения второй БД.
Может есть и другие идеи...
А почему репликтор не подходит? Тебе же нужна именно репликация, а то что нужно передавать текстовые файлы чем плохо? Собственно она самая родимая и получится.
P.S. Связь понятие довольно растяжимая


таблицы связанны...
Но, кто не рискует, то не пьёт шампанское....
Потому что курьер на велосипеле туда не доедет, а связь тока на несеолько секунд чтоб передать файлики.
Это всё равно что если бы тебе сказали: отправлять мыло один раз в день и аттачи только txt или ini или им подобные.
Но, кто не рискует, то не пьёт шампанское....
.А почему репликтор не подходит
Потому что курьер на велосипеле туда не доедет, а связь тока на несеолько секунд чтоб передать файлики.
Это всё равно что если бы тебе сказали: отправлять мыло один раз в день и аттачи только txt или ini или им подобные.
-
- Сообщения: 6
- Зарегистрирован: 27 окт 2004, 06:35
Во как вопрос перевернулся
В принципе мой вариант подойдет, только вместо
у меня получится 6 одиночных запросов:
что повлечет за собой сильное "разбухание" текстовика. С другой стороны если update очень серьёзный, и в присвоении, и в where много всяких условий(или не дай бог select из других таблиц), а в результате обрабатывается не много записей, то мой вариант будет быстрее отрабатывать.
Например:
может обрабатываться очень долго, в то время как набор
скорее всего обработается за доли секунд
Можно использовать дату, время, тип операции и т.д. последнего изменения записи и написать програмку, которая выбирает всё с последнего переноса, и потом update в другую БД.

В принципе мой вариант подойдет, только вместо
Код: Выделить всё
update table set field1 = value where id between 10 and 15
Код: Выделить всё
update table set field1 = value where id 10
update table set field1 = value where id 11
...
update table set field1 = value where id 15
Например:
Код: Выделить всё
update table set
field1 = (select count(*) from table2 t2 where (...) )
where id in (select distinct field1 from table3 where (...) )
Код: Выделить всё
update table set field1 = value where id 10
update table set field1 = value where id 11
...
update table set field1 = value where id 15
Можно использовать дату, время, тип операции и т.д. последнего изменения записи и написать програмку, которая выбирает всё с последнего переноса, и потом update в другую БД.

Попробуй, о результатах должить сюда, тем более что еще нужно доделать и додумать кое-что по алгоритму.
И еще, по описанию работы
писать в txt не обязательно, можно в какую-нибудь табличку, и потом в программе select ... from table order by datetime_field что бы сохранить последовательность.Klyk писал(а):На самом деле зачем это всё надо.
Удачи.
не, запросов типа
скорее всего не будет.
Попробуем-с...
Что получится расскажу
)
Спасибо
))
Код: Выделить всё
update table set
field1 = (select count(*) from table2 t2 where (...) )
where id in (select distinct field1 from table3 where (...) )
Попробуем-с...
Что получится расскажу

Спасибо

блин, это и есть репликация. зачем тебе sql-скрипты??? Не морочь голову - в топике есть действительно интересные письма, но они тебе СОВСЕМ без надобности. потому что тебе надо просто обеспечить самую что ни на есть стандартную репликацию. Реплицируемые записи можно сбрасывать хоть в текстовый файл, затем в zip, и тащить к другой БД на дискете.Klyk писал(а):На самом деле зачем это всё надо.
Есть 2 БД, связь между которыми - невозможна, следовательно репликатор неподходит. А изменения в одной БД надо отображать в другой. Есть возможность передачи только текстовых файлов (раз в сутки).
Вот я и думал создавать SQL скрипты при изменении данных в одной БД и выполнять этот скритп для изменения второй БД.
А "репликация" путем передачи SQL уже обсуждалась в e.p.i - ни для чего кроме как сохранения информации о том, какой клиент выдавал какой запрос, это не годится. т.е. лог SQL команд использовать для репликации НЕЛЬЗЯ.
В твоем же случае при мизерных (по кол-ву данных) изменениях в БД у тебя будет генериться огромное количество SQL, т.е. производительность просто увянет, особенно если в задаче будет update, обновляющий 100-200 записей одновременно (!).
Deniz писал(а):Например для логирования действий можно писать во внешнюю таблицу например так:Внимание, вопрос. Що будем делать с этой записью в external table в случае ежели за оным update последовал rollback транзакции, в которой он выполнялся?Код: Выделить всё
create trigger au_triggername for tablename after update position 0 as begin .... insert into ext_table(..., fields_changed, sql_type, sql_text) values (..., fields_count, 'update', :s_sql); end