SQL * Plus, @ ve göreli yollar


9

Her nasılsa, SQL * Plus'ın (en azından Windows'ta) çağrıldığında @@ve yol tek veya çift nokta ile başladığında göreli yol içeren bir komut dosyasını bulamıyor gibi görünüyor .

Örneğin, altında x:\some\whereaşağıdaki dizin yapısına sahibim:

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

Yani: iki script.sqlama farklı yerlerde.

script.sqlAz altındaki içerik x:\some\wheresadece

prompt SCRIPT root

diğerinin script.sqliçeriği ise

prompt SCRIPT main-dir/main-subdir

call-script.sql okur

@@script.sql
@ script.sql

beklenen çıktı

SQL * Plus'ı çalıştırıp x:\some\wherebir

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

Çıktı

SCRIPT main-dir/main-subdir
SCRIPT root 

Bu beklenir, çünkü tek @SQL * Plus'ın başlatıldığı @@yolları aramalı ve içeren komut dosyasının dizinindeki yolları aramalıdır.

beklenmedik çıktı

Şimdi , eğer bunu değiştirirsem call-scripts.sql:

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

çift @@, davranışını değiştiriyor gibi görünüyor, çünkü SQL * Plus'ın başladığı yerden yollar arıyor ve çıktı şimdi olacak

SCRIPT root
SCRIPT root

hangi değil beklediğim.


Bu davranış bir yerde belgelenmiş ve daha da önemlisi, call-scripts.sqlgöreli yolları ( @@../../other-dir/other-sub-dir/script) doğru çağırmak için nasıl değiştirmek zorundayım ?


SQLPATH ortam değişkeniniz nedir? Bu, hangi dizinlerin aranacağını etkiler.
Philᵀᴹ


Linux altında aynı davranış, FWIW. (Ve ve işareti @ değildir, gerçek bir isme sahip gibi görünmez ). Tutarsız olduğu için böcek gibi görünüyor. Akla gelen tek şey, bir değişkeni tam yol ile üst düzey komut dosyası ayarlamak ve buna dayalı her şeyi yapmaktır, ancak aşağıdaki dizin yapısı sabit olmadığı sürece bu çok uygun değildir.
Alex Poole

@ Vs ve işaretleri şey işaret ettiğiniz için teşekkürler ... Bunu bilmeliydim, ama yazı yazarken gerçekten dikkat etmedi. Artık başlıkta düzeltildi.
René Nyffenegger

2
Sadece sqlplus'a saldırdım strace. İlgili aramalar şunlardır : pastebin.com/cVK1QQu4 Yapıştırmalı çıktıda görülenleri açmaya çalışmadan önce "script.sql" dosyalarına başka bir dizinde erişmeye veya bunlara erişmeye çalışmadığını unutmayın.
Philᵀᴹ

Yanıtlar:


7

Evet, bu uzun zamandır var olan ve muhtemelen yakın gelecekte düzeltilmeyecek olan Hata 2391334.

Bu çevrede çalışma bir yolu komut yolunu "bilmek" dir olmadan aslında zor bu yolu kodlama. SQLPlus'ta bunu yapmak için bir hile gerektirir - varolmayan bir dosyayı çalıştırmayı denerseniz, yol adını içeren bir hata iletisi alırsınız.

İşte işte bunun bir demosu. Senaryonuzu taklit etmek için:

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

Yapabileceğimiz, yolu alacak olan call_script.sql dosyasının önüne bazı komutlar eklemektir. Biraz tuhaf görünüyor, ancak değiştirmenize gerek yok - yapıştırdığınız sabit bir şey

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

Burada olan şu ki, varolmayan bir komut dosyası çalıştırıyoruz:

"SP2-0310: dosya açılamıyor" path \ _nonexistent_script.sql "

küçük bir regexp ile yolu çıkarabilir, bir SQLPlus değişkeninde saklayabilir ve daha sonra bu noktadan itibaren kullanabiliriz.

Yani call_script.sql dosyanızın son sürümü şöyle görünecektir

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

ve bunu çalıştırdığımızda aşağıdakileri elde ederiz

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

ve işte gidiyorsun :-)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.