SQL * Plus, @ 및 상대 경로


9

어떻게 든 SQL * Plus (적어도 Windows에서는)는 호출 @@될 때와 경로가 단일 또는 이중 점으로 시작할 때 상대 경로가있는 스크립트를 찾을 수없는 것 같습니다 .

예를 들어, 아래 x:\some\where디렉토리 구조는 다음과 같습니다.

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

즉, 둘이 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 환경 변수는 무엇으로 설정되어 있습니까? 검색되는 디렉토리에 영향을줍니다.
Philᵀᴹ


Linux에서 동일한 동작, FWIW. (그리고 앰퍼샌드는 @이 아니라 &이며; 실제 이름이없는 것 같습니다 ). 일관성이 없기 때문에 버그 인 것 같습니다. 염두에 두어야 할 것은 변수를 전체 경로로 최상위 스크립트로 설정하고 그에 따라 모든 것을 수행하는 것입니다.하지만 그 아래의 디렉토리 구조가 고정되어 있지 않으면 편리하지 않습니다.
Alex Poole

@ vs 앰퍼샌드 를 지적 해 주셔서 감사합니다 ... 알았어 야했지만 게시물을 쓸 때 실제로주의를 기울이지 않았습니다. 제목이 수정되었습니다.
René Nyffenegger

2
방금 sqlplus를 공격했습니다 strace. 여기에 관련 통화의 : pastebin.com/cVK1QQu4의 는 페이스트 빈 출력에서 볼 수있는 사람을 열 시도하기 전에 다른 디렉토리에 합계 또는 액세스 "script.sql"파일을 시도하지 않았다하는 것으로.
Philᵀᴹ

답변:


7

예, 이것은 버그 2391334로 오랫동안 사용되어 왔으며 가까운 시일 내에 수정되지 않을 것입니다.

이 문제를 해결하는 한 가지 방법은 실제로 해당 경로를 하드 코딩 하지 않고 스크립트의 경로를 "인식"하는 것 입니다. 존재하지 않는 파일을 실행하려고하면 경로 이름이 포함 된 오류 메시지가 표시됩니다.

여기 실제 데모가 있습니다. 귀하의 시나리오를 모방하기 위해 다음을 얻었습니다.

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.