2011-06-02 25 views
1

我試圖將listener.ora的內容寫入另一個文件,而不在目錄中進行硬編碼。listener.ora的PL/SQL Oracle_home目錄內容

當我指定的目錄中,本來它的工作:

'C:\app\OracleDB11g\product\11.2.0\dbhome_1\NETWORK\ADMIN' 

但我不想硬編碼,因爲該腳本將被用於不同的機器/ DBS。

CREATE OR REPLACE DIRECTORY LISTENERDIR AS '%ORACLE_HOME%/NETWORK/ADMIN/'; 
declare 
f utl_file.file_type; 
fOUT utl_file.file_type; 
s varchar2(200); 
begin 
f := utl_file.fopen('LISTENERDIR','listener.ora','R'); 
loop 
    utl_file.get_line(f,s); 
    fOUT := utl_file.fopen('OUTPUT','oraDBoutput.txt','A'); 
    utl_file.put_line(fOUT,s); 
    utl_file.fclose(fOUT); 
end loop; 
exception 
when NO_DATA_FOUND then 
    utl_file.fclose(f); 
end; 
/

drop directory LISTENERDIR; 

我已經使用其他斜線,小瓶蓋,不同的變化,如\NETWORK\ADMIN嘗試,甚至指定從dbms_system.get_env()但沒有用的變量。

回答

1
CREATE OR REPLACE DIRECTORY LISTENERDIR AS 

'%ORACLE_HOME%/ NETWORK/ADMIN /';

我們不能這樣做。我們必須在創建目錄對象時指定絕對OS路徑。這就是爲什麼它在你使用完整路徑時有效。它在文檔中。 Find out more

如果你真的想動態創建庫,你可以做這樣的:

SQL> conn/as sysdba 
Connected.  

SQL> declare 
    2  l_home varchar2(255); 
    3 begin 
    4  dbms_system.get_env('ORACLE_HOME', l_home); 
    5 
    6  execute immediate 'create directory listenerdir as ''' 
    7   ||l_home||'\NETWORK\ADMIN'''; 
    8 end; 
    9/

PL/SQL procedure successfully completed. 

SQL> 
SQL> select directory_path 
    2 from all_directories 
    3 where directory_name = 'LISTENERDIR' 
    4/

DIRECTORY_PATH 
-------------------------------------------------------------------------------- 
C:\app\oracle\product\11.1.0\db_1\NETWORK\ADMIN 

SQL> 

DBMS_SYSTEM.GET_ENV()保證返回正確的目錄爲$ ORACLE_HOME用來啓動實例;其他方法不是。默認情況下,只有SYS用戶對DBMS_SYSTEM具有權限,但只有受限制帳戶應具有CREATE ANY DIRECTORY權限。


不知道你爲什麼使用PL/SQL來做到這一點。我總是贊成儘可能使用數據庫來做,但是這讓我覺得它是一種執行簡單OS副本的過度複雜的方式。

+0

謝謝!有效。我所要添加的只是將內容緩存到文件:) – sanc 2011-06-07 03:42:45

2

看看這對你的作品:

SELECT SUBSTR(file_spec, 1, INSTR(file_spec, '\', -1, 2) -1) 
FROM dba_libraries 
WHERE library_name = 'DBMS_SUMADV_LIB'; 

發現here。和here

這將編程方式獲得您的ORACLE_HOME,從那裏你可以創建你的Oracle目錄對象:

DECLARE 
    dir VARCHAR2(2000); 
BEGIN 
    SELECT 'CREATE OR REPLACE DIRECTORY LISTENERDIR AS '''|| 
      SUBSTR(file_spec, 1, INSTR(file_spec, '\', -1, 2) -1) ||'''' 
    INTO dir 
    FROM dba_libraries 
    WHERE library_name = 'DBMS_SUMADV_LIB'; 

    EXECUTE IMMEDIATE dir; 
    ... do your stuff here... 
    EXECUTE IMMEDIATE 'DROP DIRECTORY LISTENERDIR'; 
END; 
/
+0

您提供的兩個鏈接都指出,這不一定是實際的Oracle Home(尤其是XP)。 – APC 2011-06-02 05:48:57

+0

的確如此,但這是我能找到的唯一幫助。另外,我從來沒有聽說過dba_libraries,所以這是一個有用的練習;-) – DCookie 2011-06-02 05:58:40