Буквально на днях у меня возникла очень интересная задача — вызов шелл-скрипта из триггера в Oracle. Самый простой выход в этой ситуации — хранимая процедура в Java, но редакция Oracle, для которой нужно было выполнять действия — XE, не имеющая такой возможности.
Гугл дает довольно много советов, как реализовать процедуру, ссылающуюся на библиотеку Си, но мне такие инструкции в чистом виде не подошли, пришлось добавить еще несколько советов, в чем мне тоже помог гугл.
Я не помню ссылок на ресурсы, где получал ответы, но попробую рассказать всю цепочку действий.
Итак, все начинается с создания необходимой библиотеки C, которая будет вызывать оболочку внутри системы.
Код библиотеки элементарен:
После создания файла с исходным кодом необходимо скомпилировать из него саму либу, для чего мы будем использовать gcc и ld. Допустим, источник называется shell.c.#include <stdio.h> #include <stdlib.h> #include <string.h> void sh(char*); void sh(char* cmd) { system(cmd); }
gcc -fPIC -DSHARED_OBJECT -c shell.c
ld -shared -o shell.so shell.o
Для меня, как программиста C# и Java, было неожиданностью, что для того, чтобы все работало, библиотека должна быть скомпилирована в операционной системе с той же разрядностью, что и на машине под управлением Oracle. Теперь у нас есть библиотека, которая может выполнять в оболочке то, что передается ей в качестве параметра — отлично.
Следующим шагом будет создание процедуры в Oracle. Мы начинаем этот шаг с копирования полученной библиотеки в $ORACLE_HOME/bin — как показала практика, библиотека может не работать, если находится на другом маршруте.
В самом Oracle мы создаем внешнюю библиотеку, заменяя путь $ORACLE_HOME. create or replace library shell_lib is '$ORACLE_HOME/bin/shell.so';
Имея библиотеку, создадим процедуру, которая будет вызывать функцию этой библиотеки.
create or replace procedure shell(cmd IN char)
as external name "sh" library shell_lib language C parameters (cmd string);
На этом этапе у Oracle уже есть готовая процедура, вызывающая оболочку, но для ее работы может потребоваться настройка самого Oracle — нужно исправить слушателя.
Пойдем $ORACLE_HOME/сеть/администратор/ где мы открываем файл tnsnames.ora и проверьте наличие описания для подключения по протоколу IPC, там должно быть написано что-то вроде EXTPROC_CONNECTION_DATA =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = IPC)(KEY = extproc1)))
(CONNECT_DATA =(SID = plsextproc)(PRESENTATION = RO))
)
Если такой строки нет, то создайте ее, если есть, то посмотрите значение КЛЮЧ и запомни это.
Затем откройте файл слушатель.
ора , расположенный там, и проверьте, может ли слушатель, к которому вы подключаетесь, подключиться по протоколу IPC, настройка будет выглядеть примерно так: (ADDRESS = (PROTOCOL = IPC)(KEY = extproc1))
Если такой настройки нет, добавьте ее; если есть, сверьте значение KEY со значением из файла tnsnames.ora, они должны совпадать.
Если хотя бы один файл tnsnames.ora или Listener.ora изменился, необходимо перезапустить прослушиватель: lsnrctl stop
lsnrctl start
После выполнения этих простых шагов становится возможным вызвать оболочку из любой процедуры/функции/триггера в Oracle.
Теги: #oracle #базы данных #shell #oracle
-
Почему Резервная Копия Sql Так Важна
19 Oct, 24 -
К Вопросу О Linux (Л)
19 Oct, 24 -
Twitterspy: Ваш Личный Jabber-Шлюз В Twitter
19 Oct, 24