एसक्यूएल * प्लस, @, और रिश्तेदार पथ


9

किसी तरह, ऐसा लगता है कि एसक्यूएल * प्लस (कम से कम विंडोज पर) एक स्क्रिप्ट को एक रिश्तेदार पथ के साथ खोजने में असमर्थ है, जब बुलाया जाता है @@और जब पथ एकल या डबल डॉट के साथ शुरू होता है।

उदाहरण के लिए, 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

अपेक्षित उत्पादन

अगर मैं एसक्यूएल * प्लस से शुरुआत करता हूं x:\some\whereऔर फिर ए

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

आउटपुट होगा

SCRIPT main-dir/main-subdir
SCRIPT root 

यह अपेक्षित है, क्योंकि सिंगल को @उन रास्तों की खोज करनी है, जहाँ से SQL * प्लस को शुरू किया गया था और @@जिसमें स्क्रिप्ट की डायरेक्टरी से रास्ते खोजने थे।

अप्रत्याशित उत्पादन

अब , अगर मैं call-scripts.sqlऐसा बदलता हूं :

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

डबल @@यह व्यवहार बदलने के लिए, जबकि इसमें से रास्तों जहां एसक्यूएल * प्लस शुरू किया गया था खोज रहा है, और उत्पादन अब हो जाएगा

SCRIPT root
SCRIPT root

जो मुझे उम्मीद नहीं थी।


क्या इस व्यवहार को कहीं और प्रलेखित किया गया है, और इससे भी महत्वपूर्ण call-scripts.sqlबात यह है कि मुझे कैसे बदलना होगा ताकि यह सापेक्ष रास्तों ( @@../../other-dir/other-sub-dir/script) को सही ढंग से बुलाए?


आपका SQLPATH पर्यावरण चर किसके लिए निर्धारित है? यह प्रभावित करता है कि कौन सी निर्देशिकाएं खोजी गई हैं।
फिलो


लिनक्स, एफडब्ल्यूआईडब्ल्यू के तहत एक ही व्यवहार। (और एक एम्परसेंड है & @, नॉट @, जो एक वास्तविक नाम नहीं है )। बग लगता है, क्योंकि यह असंगत है। केवल एक चीज जो दिमाग में आती है वह है एक चर को पूर्ण स्तर के साथ शीर्ष स्तर की स्क्रिप्ट सेट करना और उसके आधार पर सब कुछ करना, लेकिन यह बहुत सुविधाजनक नहीं है जब तक कि नीचे दी गई निर्देशिका संरचना तय न हो जाए।
एलेक्स पूले

@ बनाम एम्परसैंड्स चीज़ की ओर इशारा करने के लिए धन्यवाद ... मुझे यह जानना चाहिए था, लेकिन जब मैंने पोस्ट लिखा तो मैंने वास्तव में ध्यान नहीं दिया। अब यह शीर्षक में तय हो गया है।
रेने न्यफेनेगर

2
मैंने सिर्फ sqlplus पर हमला किया strace। यहां प्रासंगिक कॉल हैं: pastebin.com/cVK1QQu4 ध्यान दें कि यह किसी अन्य निर्देशिका में "script.sql" फ़ाइलों को स्टेटबैंक आउटपुट में देखे गए लोगों को खोलने का प्रयास करने से पहले स्टेटस या एक्सेस करने का प्रयास नहीं करता था।
फिलु

जवाबों:


7

हाँ, यह बग 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: फ़ाइल खोलने में असमर्थ" पथ ​​\ _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

और वहाँ तुम जाओ :-)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.