Вызов Оболочки Из Oracle

Буквально на днях у меня возникла очень интересная задача — вызов шелл-скрипта из триггера в Oracle. Самый простой выход в этой ситуации — хранимая процедура в Java, но редакция Oracle, для которой нужно было выполнять действия — XE, не имеющая такой возможности.

Гугл дает довольно много советов, как реализовать процедуру, ссылающуюся на библиотеку Си, но мне такие инструкции в чистом виде не подошли, пришлось добавить еще несколько советов, в чем мне тоже помог гугл.

Я не помню ссылок на ресурсы, где получал ответы, но попробую рассказать всю цепочку действий.

Итак, все начинается с создания необходимой библиотеки C, которая будет вызывать оболочку внутри системы.

Код библиотеки элементарен:

  
  
  
  
  
  
   

#include <stdio.h> #include <stdlib.h> #include <string.h> void sh(char*); void sh(char* cmd) { system(cmd); }

После создания файла с исходным кодом необходимо скомпилировать из него саму либу, для чего мы будем использовать gcc и ld. Допустим, источник называется shell.c.

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

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.