1

Perl を使用して、Oracle データベースで定期的なメンテナンス タスクを実行しようとしています。データベースへのユーザー アクセス権があり、すべてのスクリプトをデータベース上でローカルに実行しています。データベースで SQL ステートメントを実行して pfile を生成し、後で表示できるように tmp フォルダーに保存したいと考えています。

ただし、システムに DBI がインストールされていないため、DBI を使用して DB に接続し、SQL ステートメントを実行することはできません。私は管理者アクセス権を持っていますが、DBI の使用を避けようとしています。これは、このスクリプトが各マシンにローカルに展開され、すべてのデータベースに DBI をインストールしたくないためです。DBでローカルにスクリプトを実行している場合、DBIを使用せずにOracle dbでSQL文を実行する方法はありますか?

たとえば、pfile を生成するには、次の SQL ステートメントを実行する必要があります。

create pfile='/tmp/pfile.ora' from spfile

これを手動で行っていた場合は、su asを実行してからマシンをoracle起動sqlplusして SQL ステートメントを実行する必要があります。system()これらのコマンドをヒアドキュメントに入れてから、関数にスローすることで、これをエミュレートしようとしました。

my $result =<<EOF;
su - oracle
sqlplus / as sysdba
create pfile='/tmp/pfile.ora' from spfile;
exit
EOF

system($result);

しかし、コマンドが終了するのを待ってから残りのステートメントを続行するため、これは機能しませんsu - oracle(これもずさんなやり方のように感じます)。また、シェルスクリプトを作成し、system("sh script.sh") を使用して perl 内からスクリプトを実行することで同じことを試みましたが、これは同じ結果をもたらしました。

私がやろうとしていることを達成する方法はありますか?それとも、DBI 以外にこれを行う方法はないことを上層部に伝えるべきでしょうか?

4

2 に答える 2

2

複数のコマンドを実行し、その間に応答を待機するには、 Expectモジュールを使用する必要があります。ただし、これは perl コアには含まれていないため、DBI を持っていない場合は、おそらく Expect も持っていません。いずれにせよモジュールをインストールするつもりなら、DBI をインストールして正しい方法で行うこともできます。

ただし、次のようなものを使用して、これを 1 行で実行できる場合があります。

open my $of, ">", "/tmp/pfile.sql";
$of->print("create pfile='/tmp/pfile.ora' from spfile");
close $of;
system("su - oracle -c 'sqlplus / as sysdba < /tmp/pfile.sql'");
于 2013-11-06T17:35:37.917 に答える
0

SQLコマンドのセットを文字列に配置し、system()関数を使用して実行することで、この作業を行うことができました。

my $result = 'sqlplus / as sysdba <<EOF;
create pfile=\'/tmp/pfile.ora\' from spfile;
exit;
EOF
';

system($result);

最初の行は、次のヒアドキュメントを で実行するように指示しsqlplus / as sysdbaます。バックスラッシュは、pfile ディレクトリ内の単一引用符をエスケープします。また、oracle実行できるのは のみsqlplusであるため、スクリプトを として実行しているとすでに推定されており、スクリプトを実行するoracle必要はありませsuん。

于 2013-11-06T21:54:58.400 に答える