SQL * Plus、@、および相対パス


9

どういうわけか、SQL * Plus(少なくともWindowsでは)が呼び出され@@、パスが単一または二重のドットで始まる場合、相対パスを持つスクリプトを見つけることができないようです。

たとえばx:\some\where、次のディレクトリ構造があります。

script.sql
main-dir\main-sub-dir
              call-script.sql
              script.sql

つまり、2つですscript.sqlが、場所が異なります。

script.sql直下の内容x:\some\whereは単純です

prompt SCRIPT root

他方script.sqlのコンテンツは

prompt SCRIPT main-dir/main-subdir

call-script.sql 読む

@@script.sql
@ script.sql

期待される出力

からSQL * Plusを起動してからx:\some\where

@main-dir/main-sub-dir/call-scripts

出力は

SCRIPT main-dir/main-subdir
SCRIPT root 

シングル@はSQL * Plusが開始された場所@@からのパスを検索し、含まれているスクリプトのディレクトリからパスを検索することになっているため、これは予想されたものです。

予期しない出力

、私がcall-scripts.sqlそう変更した場合:

@@./script.sql
@ ./script.sql

double @@は、SQL * Plusが開始された場所からパスを検索するという点で、動作を変更しているように見え、出力は次のようになります。

SCRIPT root
SCRIPT root

これは私が期待したものではありません


この動作はどこかに文書化されていますか、そしてもっと重要なcall-scripts.sqlことは、相対パス(@@../../other-dir/other-sub-dir/script)を正しく呼び出すように変更するにはどうすればよいですか?


SQLPATH環境変数は何に設定されていますか?検索するディレクトリに影響します。
フィロ2012年


Linux、FWIWでも同じ動作。(そして、アンパサンドは&であり、@;でありません本当の名前はないようです)。一貫性がないため、バグのようです。頭に浮かぶのは、フルパスで変数を最上位スクリプトに設定し、それに基づいてすべてを実行することだけですが、その下のディレクトリ構造が修正されない限り、それはあまり便利ではありません。
Alex Poole

@ vsアンパサンドのことを指摘してくれてありがとう...私はそれを知っているべきでしたが、私が投稿を書いたとき、私は本当に注意を払いませんでした。タイトルで修正されました。
ルネNyffenegger

2
でsqlplusを攻撃しましたstrace。:ここでは、関連する通話ですpastebin.com/cVK1QQu4注それはペーストビン出力で見られるものを開こうとする前に、任意の他のディレクトリ内のstatまたはアクセス「script.sql」ファイルにしようとしなかったことを。
フィロ2012年

回答:


7

うん、これは長い間存在していたバグ2391334であり、おそらく近い将来には修正されないでしょう。

これを回避する1つの方法は、実際にパスをハードコーディングすることなく、スクリプトのパスを「知る」ことです。SQLPlusでこれを行うには、トリックが必要です。存在しないファイルを実行しようとすると、パス名を含むエラーメッセージが表示されます。

これが実際のデモです。私が持っているあなたのシナリオを模倣するために:

c:\temp\demo
   script.sql
   maindir
      subdir
         call_script.sql
         script.sql

実行できることは、パスを取得するcall_script.sqlの前にいくつかのコマンドを追加することです。少し奇妙に見えますが、変更する必要はありません-貼り付けた固定されたものです

set termout off
spool _path_finder.sql
@@_nonexistent_script.sql
spool off;

var path varchar2(100);
set serverout on
declare
  output varchar2(1000) := regexp_replace(replace(q'{
@_path_finder.sql
}',chr(10)),'.*"(.*)".*','\1');
begin 
  :path:=substr(output,1,length(output)-24);
end;
/
col path new_val path
select :path path from dual;
set termout on

ここで何が起こっているのか、存在しないスクリプトを実行しています。

"SP2-0310:ファイル" path \ _nonexistent_script.sql "を開けません"

したがって、小さな正規表現を使用して、パスを抽出し、SQLPlus変数に格納して、その時点から使用できます。

したがって、call_script.sqlの最終バージョンは次のようになります。

set termout off
spool _path_finder.sql
@@_nonexistent_script.sql
spool off;

var path varchar2(100);
set serverout on
declare
  output varchar2(1000) := regexp_replace(replace(q'{
@_path_finder.sql
}',chr(10)),'.*"(.*)".*','\1');
begin 
  :path:=substr(output,1,length(output)-24);
end;
/
col path new_val path
select :path path from dual;
set termout on
prompt path was &path      

@@&path\script.sql
@&path\script.sql

それを実行すると、次のようになります

SQL> @maindir\mainsubdir\call_script
path was maindir\mainsubdir
script in subdir
script in subdir

そしてそこに行く:-)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.