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

คู่@@ดูเหมือนว่าจะเปลี่ยนพฤติกรรมของมันในการที่จะค้นหาเส้นทางจากที่เริ่มต้น SQL * Plus และผลลัพธ์จะเป็น

SCRIPT root
SCRIPT root

ซึ่งไม่ใช่สิ่งที่ฉันคาดหวัง


พฤติกรรมนี้มีการบันทึกไว้ที่ใดที่หนึ่งและที่สำคัญฉันต้องเปลี่ยนcall-scripts.sqlเพื่อให้เรียกเส้นทางสัมพัทธ์ ( @@../../other-dir/other-sub-dir/script) อย่างถูกต้องได้อย่างไร


ตัวแปรสภาพแวดล้อม SQLPATH ของคุณตั้งค่าเป็นอะไร ที่มีผลต่อไดเรกทอรีที่จะค้นหา
Philᵀᴹ

1
โดยวิธีการที่เอกสารอยู่ที่นี่: docs.oracle.com/cd/E11882_01/server.112/e16604/... docs.oracle.com/cd/E11882_01/server.112/e16604/...
Philᵀᴹ

พฤติกรรมเดียวกันภายใต้ Linux, FWIW (และแอมเปอร์แซนด์คือ &, ไม่ใช่ @; ซึ่งดูเหมือนจะไม่มีชื่อจริง ) น่าจะเป็นข้อผิดพลาดเนื่องจากมันไม่สอดคล้องกัน สิ่งเดียวที่ควรคำนึงถึงคือการตั้งค่าตัวแปรให้เป็นสคริปต์ระดับบนสุดที่มีเส้นทางแบบเต็มและทำทุกอย่างตามนั้น แต่ก็ไม่สะดวกมากเว้นแต่โครงสร้างไดเรกทอรีด้านล่างที่ได้รับการแก้ไข
Alex Poole

ขอบคุณที่ชี้ให้เห็นถึงสิ่งที่@ vs ampersands ... ฉันควรจะรู้ แต่เมื่อฉันเขียนโพสต์ฉันไม่ได้สนใจจริงๆ ตอนนี้ได้รับการแก้ไขแล้วในชื่อ
René Nyffenegger

2
ฉันเพียงแค่โจมตี sqlplus straceกับ นี่คือการเรียกที่เกี่ยวข้อง: pastebin.com/cVK1QQu4โปรดทราบว่ามันไม่ได้พยายามจัดทำหรือเข้าถึงไฟล์ "script.sql" ในไดเรกทอรีอื่น ๆ ก่อนที่จะพยายามเปิดสิ่งที่เห็นในเอาต์พุตของ pastebin
Philᵀᴹ

คำตอบ:


7

ใช่นี่คือ Bug 2391334 ซึ่งมีมานานแล้วและอาจจะไม่ได้รับการแก้ไขในอนาคตอันใกล้

วิธีหนึ่งในการแก้ไขปัญหานี้คือ "รู้" เส้นทางของสคริปต์โดยไม่ต้องเข้ารหัสฮาร์ดไดรฟ์ดังกล่าว ในการทำเช่นนี้ใน 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 "

ดังนั้นด้วย regexp เพียงเล็กน้อยเราสามารถแยกพา ธ เก็บไว้ในตัวแปร 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.