Oracleからのシェル呼び出し

先日、非常に興味深いタスクがありました-Oracleのトリガーからシェルスクリプトを呼び出すことです。 この状況で最も簡単な解決策は、Javaのストアドプロシージャですが、アクションを実行する必要があったOracleエディション-XEでは、そのような可能性はありません。

GoogleはCライブラリを参照する手順を実装する方法について多くのヒントを提供していますが、純粋な形ではそのような指示は私には役に立たなかったので、いくつかのヒントを完成させる必要がありました。 回答を受け取ったリソースへのリンクを覚えていませんが、一連のアクション全体を伝えようとします。



そのため、すべては必要なCライブラリを作成することから始まります。Cライブラリはシステム内でシェルを呼び出します。 ライブラリコードは基本です。



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





ソースコードを使用してファイルを作成したら、lib自体をコンパイルする必要があります。そのためにgccとldを使用します。 ソースコードがshell.cであるとします。



 gcc -fPIC -DSHARED_OBJECT -c shell.c ld -shared -o shell.so shell.o
      
      





私にとって、C#とJavaのプログラマーとして、すべてが機能するためには、Oracleを搭載したマシンと同じビット深度のOSでアセンブルしなければならないことに驚きました。



パラメータで渡されたものをシェルで実行できるライブラリがあります-すばらしいです。



次のステップは、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 / network / admin /に移動し、 tnsnames.oraファイルを開いて、IPC接続の説明を確認します。次のように記述します。



 EXTPROC_CONNECTION_DATA = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = IPC)(KEY = extproc1))) (CONNECT_DATA =(SID = plsextproc)(PRESENTATION = RO)) )
      
      





そのような行がなければ、それを作成し、もしあれば、 KEY値を見て覚えておいてください。

その後、同じ場所にあるlistener.oraファイルを開き、接続先のリスナーがIPCを介して接続できるかどうかを確認します。セットアップは次のようになります。



 (ADDRESS = (PROTOCOL = IPC)(KEY = extproc1))
      
      





そのような設定がない場合-追加、ある場合-KEY値をtnsnames.oraファイルの値と確認し、一致する必要があります。

少なくとも1つのtnsnames.oraまたはlistener.oraファイルが変更された場合、リスナーをリロードする必要があります。



 lsnrctl stop lsnrctl start
      
      





これらの簡単なアクションを実行した後、Oracleの任意のプロシージャ/関数/トリガーからシェルを呼び出すことができます。



All Articles