Страница 1 из 1

EXECUTE STATEMENT на другой базе

Добавлено: 21 янв 2013, 09:31
AlekseyTabakov
Добрый день.
Используем БД Firebird 2.5.xxxx.
Появилась задача хранить лог базы в отдельной базе. Как я понял, в этом может помочь использование execute statement. Но решил для начала научиться просто что-либо записывать в другую базу. Была создана отдельная база и таблица в ней следующим скриптом:

Код: Выделить всё

set SQL DIALECT 3; 
create database 'C:\Work\LOG_DEBUG.fdb' 
user 'SYSDBA' password 'masterkey' 
page_size 8192  default character set WIN1251; 
CREATE TABLE LOG_TABLES ( 
         ID               NUMERIC(18,0) NOT NULL, 
         TABLE_NAME       VARCHAR(100) CHARACTER SET UTF8, 
         OPERATION        VARCHAR(1), 
         DATE_TIME        TIMESTAMP, 
         USER_NAME        VARCHAR(100), 
         NUM_TRANSACTION  INTEGER ); 
Пытаюсь из своей базы выполнит запрос вида:

Код: Выделить всё

execute block 
as 
begin 
    execute statement 'insert into LOG_TABLES(ID) values(1)' 
    on external 'C:\Work\LOG_DEBUG.fdb' 
    with autonomous transaction 
    as user 'SYSDBA' password 'masterkey'; 
end 
Выдаётся ошибка "Firebird error. unknown ISC error 335544921."
Подскажите пожалуйста, что я делаю не так? Каковы возможные причины ошибки?

Re: EXECUTE STATEMENT на другой базе

Добавлено: 21 янв 2013, 11:55
hvlad
335544921 это isc_eds_connection
Т.е. проблемы с коннектом на внешнюю БД.

> "Firebird error. unknown ISC error 335544921."
Это кто такое выдал ?

Выполните запрос в том же isql и смотрите нормальный полный текст ошибки.

Re: EXECUTE STATEMENT на другой базе

Добавлено: 21 янв 2013, 12:50
kdv
попутно вопрос - а почему ID это numeric(18,0) ? То есть, почему не BIGINT, раз уж вы хотите int64 в качестве идентификатора использовать? В базе ваш numeric(18,0) будет целым числом, а на клиента будет приходить в вещественное число. И при определенных значениях можно будет получить потерю цифр.

Re: EXECUTE STATEMENT на другой базе

Добавлено: 22 янв 2013, 11:38
AlekseyTabakov
kdv, да, вы правы, правильнее взять тип BIGINT. не совсем верно я сформировал таблицу. впрочем, суть моего вопроса не в этом.

hvlad. этот текст ошибки выдала мне моя основная БД при попытке выполнить скрипт, добавляющий запись в базу лога.
при попытке проиграть этот скрипт в самой базе LOG_DEBUG была выдана ошибка "Invalid token.Dynamic SQL Error.SQL error code = -104.Token unknown - line 5, column 5.on.". Полагаю, это означает, что не подерживается синтаксис execute statement on external...

Кажется, я понял свою ошибку. Её суть в том, что основная база лежит на сервере, где установлен Firebird 2.5, что позволяет в основной базе использовать execute statement on external. Но базу LOG_DEBUG я создал в своём компе, а у меня Firebird 2.1, в библиотеках которого нет такой реализации оператора execute statement. Попробую установить у себя 2.5 и ещё раз всё попробовать.

Re: EXECUTE STATEMENT на другой базе

Добавлено: 22 янв 2013, 12:28
AlekseyTabakov
Да, это помогло. Но, к сожалению, появилась другая проблема.
Теперь попытка проиграть скрипт в основной базе выдаёт ошибку "Unsuccessful execution caused by system error that does not preclude successful execution of subsequent statements.
Execute statement error at attach :
335544831 : Access to database "C:\WORK\LOG_DEBUG.FDB" is denied by server administrator
Data source : Firebird::C:\Work\LOG_DEBUG.FDB."

Попытка проиграть этот же скрипт в базе лога была успешной.
Подскажите пожалуйста, какова возможная причина того, что что сервер базы лога не даёт доступ при попытке записи?

Re: EXECUTE STATEMENT на другой базе

Добавлено: 22 янв 2013, 14:05
hvlad

Re: EXECUTE STATEMENT на другой базе

Добавлено: 22 янв 2013, 15:00
kdv
Теперь попытка проиграть скрипт
скрипт - это набор SQL операторов. В Firebird (и InterBase) операторы выполняются по одному. Инструменты (isql, IBExpert, и т.п.) которые могут выполнять скрипты, парсят их и отправляют на сервер по одному.
А execute block - это не скрипт, это один оператор. Да, который может выполнять несколько, но это относится и к процедурам и триггерам. Собственно, execute block это выполнение процедуры без ее предварительного сохранения в системных таблицах.