IBEScript -прекрасная утилита от компании HK-Software. Эта же компания написала легендарный IBExpert – инструмент для администрирования и разработки баз данных Firebird и Interbase.
И так, что такое IBEScript? Эта приложение является значительно расширенным аналогом isql.exe (консольная утилиты предоставляющей доступ через SQL до баз Firebird).
Кроме дублирования функционала isql-утилиты, IBEScript расширен специальными командами под названием IBEBlock. Количество команд переваливает за 3 сотни. Понятно, что такое количество новых функций делает из утилиты предназначенную в первую очередь для написания хранимых процедур и простых SQL запросов – мощный инструмент на многие случаи жизни.
Но в основном IBEScript используется для написания скриптов которые работают с базами Firebird. И очень жалко что не для всех баз данных такой инструмент сущесвует.
Для тех, кто будет читать дальше, поясняю что все здесь написано рассчитано на людей знакома с хранимыми процедурами Firebird. Приступим.
Скрипт начинается как хранимая процедура в Firebird
execute ibeblock as begin -- текст скрипта end
Для того что бы его запустить создаем bat-файл следующего содержания:
Cd . IBEScript.exe "script.ibb" -Dc:db.fbd -Usysdba –Pmasterkey Pause
script.ibb – это путь до скрипта.
Далее идут параметры подключения (-Dc:db.fbd -Usysdba –Pmasterkey). Их можно не указывать если вы подключайтесь к базе в самом скрипите или например берете эти данные из ini файла (А это IBEBlock позволяет!)
И так вы можете теперь позапускать скрипт. Он правда ничего не делает 🙂
Рассмотрим некоторые примеры. Качаем файл.
Script1.ibb
Показывает возможность логирования действий скрипта. Логирование всегда полезно)
execute ibeblock as begin -- лог файл с информацие log_file = ibec_GetRunDir() || 'script.log'; if(ibec_FileExists(:log_file)) then begin -- файл открываем log_fs = ibec_fs_OpenFile(:log_file, __fmOpenReadWrite); ibec_fs_Seek(log_fs,0,__soFromEnd); end else -- файл создаем log_fs = ibec_fs_OpenFile(:log_file, __fmCreate); s = ibec_Now()||' - Начало работы скрипта'; ibec_Progress(s); ibec_fs_WriteLn(log_fs, s); end
Тут используются следующие ibeblock функции:
- ibec_GetRunDir – возвращает каталог из которого запущен IBScript или IBExprt выполняющий текущий скрипт.
- ibec_FileExists – проверка наличия файла
- ibec_fs_OpenFile – открытие файла или создаем его
- ibec_fs_Seek – Перейти к определенной позиции в файле. В нашем случае в конец файла.
- ibec_fs_WriteLn – пишем в файл строку с переходом на следующую
- ibec_Now – текущее время и дата
script2.ibb
Предположим вам понадобилось перенести часть данных из одной базы в другую. Данный скрипт показывает, как организовать подключение в данном случае.
Я уже упомянул выше, что при запуске скрипта можно не упоминать параметры подключения к базе. IBEScript позволяет передавать переменные из командной строки в скрипт. Это дествительно делает скрипты гибче.
Запустите base_create.cmd для создания тестовых баз: c:base_new.fdb и c:base_old.fdb
base_new – пустая, а base_old – с данными.
Теперь посмотрим, как запускается скрипт который работает с этими базами:
set old_base=127.0.0.1:C:base_new.fdb set new_base=127.0.0.1:C:base_old.fdb IBEScript.exe "script2.ibb" -GOldBase="%old_base%" -GNewBase="%new_base%"
Для того что бы получить эти данные в скрипите пишем:
-- получаем пути для соединения OldBase = ibec_GetGlobalVar('OldBase', '127.0.0.1:C:BASE_OLD.FDB'); NewBase = ibec_GetGlobalVar('NewBase', '127.0.0.1:C:BASE_NEW.FDB');
Затем создаем строку подключения к базе и само подключение:
StrConnect = 'DBName="'||OldBase||'"; User=SYSDBA; Password=masterkey; Names=WIN1251; SqlDialect=3;'; DBOld = ibec_CreateConnection( __ctFirebird, StrConnect); StrConnect = 'DBName="'||NewBase||'"; User=SYSDBA; Password= masterkey; Names=WIN1251; SqlDialect=3;'; DBNew = ibec_CreateConnection( __ctFirebird, StrConnect);
Теперь для того что бы обратится к одной или к другой базе нам достаточно написать предварительно ibec_UseConnection(ИмяСоединеия).
Скрипт полностью.
execute ibeblock as begin -- лог файл с информацие log_file = ibec_GetRunDir() || 'script2.log'; if(ibec_FileExists(:log_file)) then begin -- файл открываем log_fs = ibec_fs_OpenFile(:log_file, __fmOpenReadWrite); ibec_fs_Seek(log_fs,0,__soFromEnd); end else -- файл создаем log_fs = ibec_fs_OpenFile(:log_file, __fmCreate); s = ibec_Now()||' - Начало работы скрипта'; ibec_Progress(s); ibec_fs_WriteLn(log_fs, s); -- получаем пути для соединения OldBase = ibec_GetGlobalVar('OldBase', '127.0.0.1:C:BASE_OLD.FDB'); NewBase = ibec_GetGlobalVar('NewBase', '127.0.0.1:C:BASE_NEW.FDB'); -- создаем соединения с базой StrConnect = 'DBName="'||OldBase||'"; User=SYSDBA; Password=z; Names=WIN1251; SqlDialect=3;'; DBOld = ibec_CreateConnection( __ctFirebird, StrConnect); StrConnect = 'DBName="'||NewBase||'"; User=SYSDBA; Password=z; Names=WIN1251; SqlDialect=3;'; DBNew = ibec_CreateConnection( __ctFirebird, StrConnect); -- указываем что работаем со старой базой ibec_UseConnection(DBOld); for select p.ID, p.NAME from partner p into :id, :name do begin s = :id||' - '||:name; ibec_Progress(s); ibec_fs_WriteLn(log_fs, s); -- переносим данные данные в новую базу ibec_UseConnection(DBNew); INSERT INTO PARTNER (ID, NAME) VALUES (:id, :name); ibec_UseConnection(DBOld); end -- сохраняем все изменения commit; s = ibec_Now()||' - Закончил работату скрипт'; ibec_Progress(s); ibec_fs_WriteLn(log_fs, s); end
Команда commit подтверждает изменения. Если ее не поставить транзакции не будут подтверждены.
Точности ради, IBEScript не копирует функциональность isql.
Он дает возможность выполнения скрипта IBExpert без наличия самого IBExpert.
А так, IBEScript кое что не умеет, по сравнению с isql — например в нем нет интерактивного режима. Понятно, что оно там и не надо — есть же сам IBE.
Сам юзаю IBEScript для накатывания патчей на базы в филиалах фирмы. Пишу скрипт, к нему инструкцию по применению — и местные админы-эникейщики справляются с этим делом.
Насчет интерактивного режима в isql — правы.
Я им не пользовался поэтому упустил из виду.
Люди добрые!!! Подскажите пожалуйста, Мне не нужно написанный скрипт запускать при промощи IBEScript, а нужно запустить с тригера в IBExpert. есть ли такая возможность, если да то какой командой?!
Скрипт использует функцию отсылки email ibec_smtp_SendMail()
Юр, не уверен что идея отправки почты через базу это хорошая идея)
Ф-ции ibec_* внедрить в PSQL не удастся. Вам надо смотреть в сторону udf.
Спасибо… Я уже понял что это практически не реально, просто скрипт делает анализ базы и когда появляется новая запись в таблице должен отправить почту, получается необходимо для решения такой вроде простой задачи необходимо писать внешнее приложение которое к примеру раз в минуту будет запускать скрипт… А для чего же еще тогда нужна функция ibec_smtp_SendMail() немогу понять…??? (((
IBExpert — и IBEScript -это и есть внешнее приложение.
Конструкции ibec_* — это не конструкции сервера, это внутренние конструкции IBExpert/IBEScript, к собственно серверу они не имеют никакого отношения.
По поводу новая запись — новая почта — путь тупиковый. Что если вставили 10000 записей? Получится 10000 писем, а кто их будет читать?
Кстати, «скрипт» — сервером тоже не выполняется. Сервер может выполнять либо отдельные команды либо команды в составе Stored Procedure, или сейчас есть еще возможность выполнить Execure Block что по сути так же процедура только на сервере не хранится.
Но те скрипты которые выполняет IBExpert — это другие скрипты, их выполняет не сервер. IBExpert разбирает скрипт по командам и те что предназначены к выполнению сервером — посылает на сервер. А те команды которые для самого IBExpert — выполняет сам. ibec_* — это как раз такие команды.
Вообще говоря если стоит именно такая задача — поймать событие — то надо наверное глянуть в сторону внешнего приложения получающего факт события по event. Event — механизм сервера позволяющий передать клиенту сообщение о наступлении некого события, которое можно инициировать в триггере.
А вообще, задача-то как выглядит, исходно?
Спасибо за мысль…
Задача состоит в том что: есть хранимая процедура которая определяет новые события в базе, и при выполнении нестандартных изменений значений, делает вставку в определенную таблицу этих же данных, после чего эти данные нужно выслать смс-кой на мобильный при помощи email (есть такая функция у мобильного оператора). Для чего я написал скрипт используя функцию ibec_smtp_SendMail(). Теперь я его запускаю раз в минуту и он определяет если новые данные в таблице для отсылки смс, и если они там есть он их отсылает…
Вообщем и все.
Задача в принципе реализована. Но я считаю что не совсем правильно запускать раз в минуту скрипт. Идея с Event наверное самая правильная. Буду пробывать реализовать это при помощи событий…
как выполнить скрипт отключения триггера в IBEBlock?
К сожалению под рукой сейчас нет Firebird
Но я бы порекомендовал выполнить эти операции сначала на копии базы через IBExpert.
Он показывает все SQL операции которые выполняет.
Можете записать их в файлик и выполнить.
А как дописать в этот скрипт условие: UPDATE dbNew.partner set name = dbOld.partner.name WHERE dbNew.partner.id = dbOld.partner.id.
Очень надо! А времени нет, чтоб книжки перечитывать..
Навскидку
Как проверить существует ли уже столбец в таблице?
ibec_ds_Post не работает вообще никак… Только можно считать в датасет а скинуть обратно в таблицу ни ни ibec_ds_Edit позволяет править активный датасет можно добавить или удалить запись, но POST ни фига не работает…
А можно ли каждое событие вывести из бд в виде http ссылки в другое ПО?
Можно ли написать такой скрипт, который мои события из БД будет направлять в другое место в виде HTTP ссылки?????