Oracle Directory目錄的知識

season0891發表於2016-03-22

在上一章介紹expdp/impdp時曾使用過DIRECTORY這個概念,下面再簡單說明下DIRECTORY的點點滴滴。

MOS上對DIRECTORY的解釋(266875.1):

(1)、基於服務端 vs 基於客戶端

DIRECTORY變數指出了expdp匯出資料泵或impdp匯入資料泵將dump檔案、log檔案以及SQL檔案(僅適用於impdp)寫到什麼路徑。

因為匯出資料泵和匯入資料泵都是基於服務端的,不是基於客戶端的,因此輸出檔案的路徑都是相對於服務端目錄的路徑。資料泵要求將目錄路徑作為一個目錄物件。一個目錄物件將檔案系統的一個目錄路徑對映為一個名稱。

(2)、如何建立一個目錄物件?

為了建立目錄,必須具有DBA角色或者賦予了CREATE ANY DIRECTORY許可權。

示例:

Window平臺

CONNECT system/manager  
CREATE OR REPLACE DIRECTORY my_dir as 'D:\DataPump';  
CREATE OR REPLACE DIRECTORY my_logdir as 'E:\logs';  
GRANT read, write ON DIRECTORY my_dir TO scott;  
GRANT read, write ON DIRECTORY my_logdir TO scott;

Unix平臺

CONNECT system/manager  
GRANT CREATE ANY DIRECTORY TO scott;  
CONNECT scott/tiger  
CREATE OR REPLACE DIRECTORY my_dir as '/usr/DataPump';  
CREATE OR REPLACE DIRECTORY my_logdir as '/usr/logs'; 

如果普通使用者被賦予了CREATE ANY DIRECTORY許可權,那麼使用者就自動具備目錄的READ和WRITE許可權

注意:CREATE DIRECTORY語句不會建立磁碟的真實目錄,如果目錄是無效的,資料泵作業會報錯:

ORA-39002: invalid operation 
ORA-39070: Unable to open the log file. 
ORA-29283: invalid file operation 
ORA-06512: at "SYS.UTL_FILE", line 475 
ORA-29283: invalid file operation

(3)、如何查詢可用的目錄?

可以使用如下SQL查詢具有READ和WRITE許可權的目錄:

SET lines 80 
COL grantee FORMAT a20 
COL privilege FORMAT a10 
SELECT directory_name, grantee, privilege 
  FROM user_tab_privs t, all_directories d   
 WHERE t.table_name(+)=d.directory_name   
 ORDER BY 1,2,3;

DIRECTORY_NAME                 GRANTEE              PRIVILEGE 
------------------------------ -------------------- ---------- 
DATA_PUMP_DIR                  EXP_FULL_DATABASE    READ 
DATA_PUMP_DIR                  EXP_FULL_DATABASE    WRITE 
DATA_PUMP_DIR                  IMP_FULL_DATABASE    READ 
DATA_PUMP_DIR                  IMP_FULL_DATABASE    WRITE 
MY_DIR                         SCOTT                READ 
MY_DIR                         SCOTT                WRITE 
MY_DIR                         SYSTEM               READ 
MY_DIR                         SYSTEM               WRITE 
MY_LOGDIR                      SCOTT                READ  
MY_LOGDIR                      SCOTT                WRITE  
MY_LOGDIR                      SYSTEM               READ  
MY_LOGDIR                      SYSTEM               WRITE  
...

(4)、需要的作業系統許可權。

對目錄物件的READ或WRITE許可權僅僅表示Oracle將會替你讀或寫這個檔案。你並沒有訪問Oracle以外檔案的許可權,除非你具備合適的作業系統許可權。

(5)、資料泵如何決定檔案的路徑

5.1 如果目錄物件是檔案標示符的一部分,那麼目錄物件指定的路徑就需要使用。在目錄MY_DIR建立dump檔案的示例:

> expdp scott/tiger DUMPFILE=my_dir:expdp_s.dmp NOLOGFILE=Y

5.2 如果目錄物件不代表一個檔案,那麼就需要使用DIRECTORY變數命名的目錄物件。目錄MY_DIR中建立dump檔案,目錄MY_DIR_LOG中建立日誌檔案的示例:

> expdp scott/tiger DIRECTORY=my_dir DUMPFILE=expdp_s.dmp \ 
LOGFILE=my_logdir:expdp_s.log

5.3 如果沒有明確目錄物件,也沒有以DIRECTORY變數命名的目錄物件,那麼環境變數DATA_PUMP_DIR將會使用。環境變數是在在執行匯出和匯入資料泵應用的客戶端系統中使用作業系統命令定義的,分配給基於客戶端環境變數的取值必須和基於服務端的目錄物件一致,且必須首先在伺服器端建立

目錄MY_DIR中建立dump檔案和MY_DIR_LOG中建立日誌檔案的示例:

在使用expdp的客戶端機器上,設定環境變數:

-- On windows, place all expdp parameters on one single line:

C:\> set DATA_PUMP_DIR=MY_DIR  
C:\> expdp scott/tiger@my_db_alias DUMPFILE=expdp_s.dmp 
LOGFILE=my_logdir:expdp_s.log

注意環境變數DATA_DUMP_DIR對應的目錄名稱是大小寫敏感的。設定錯誤的DATA_PUMP_DIR環境變數會報錯,例如:DATA_PUMP_DIR=My_Dir:

ORA-39002: invalid operation 
ORA-39070: Unable to open the log file. 
ORA-39087: directory name My_Dir is invalid

5.4 如果之前三種情況都沒有建立目錄物件,作為一個具有許可權的使用者(例如具有EXP_FULL_DATABASE或IMP_FULL_DATABASE角 色),那麼資料泵試圖使用預設的基於伺服器端的目錄物件,DATA_PUMP_DIR。理解資料泵不會建立DATA_PUMP_DIR目錄物件是非常重要 的。僅當授權使用者未使用任何之前提到的機制建立的目錄物件時,才會嘗試使用DATA_PUMP_DIR。這個預設的目錄物件必須首先由DBA建立。不要將 這個和同名的基於客戶端的環境變數相混淆。

首先,清空DATA_PUMP_DIR環境變數:

C:\> set DATA_PUMP_DIR=

建立DATA_PUMP_DIR的目錄:

CONNECT SYSTEM/MANAGER   
CREATE OR REPLACE DIRECTORY data_pump_dir AS 'D:\DataPump';   
GRANT read, write ON DIRECTORY data_pump_dir TO scott;

-- On windows, place all expdp parameters on one single line: 

C:\> expdp system/manager@my_db_alias DUMPFILE=expdp_s.dmp  
LOGFILE=expdp_s.log SCHEMAS=scott

如果SCOTT使用者不是授權使用者,不能使用預設的DATA_PUMP_DIR。

ORA-39002: invalid operation 
ORA-39070: Unable to open the log file. 
ORA-39145: directory object parameter must be specified and non-null

使用者SCOTT的解決方法:如上面5.3,SCOTT可以設定環境變數DATA_PUMP_DIR為MY_DIR:

-- On windows, place all expdp parameters on one single line:

C:\> set DATA_PUMP_DIR=MY_DIR
C:\> expdp scott/tiger@my_db_alias DUMPFILE=expdp_s.dmp 
LOGFILE=expdp_s.log SCHEMAS=scott

或者這種特定場景下,使用者SCOTT也可以有目錄DATA_PUMP_DIR的讀和寫許可權:

-- On windows, place all expdp parameters on one single line: 

C:\> set DATA_PUMP_DIR=DATA_PUMP_DIR
C:\> expdp scott/tiger@my_db_alias DUMPFILE=expdp_s.dmp 
LOGFILE=expdp_s.log SCHEMAS=scott



實驗:

建立目錄:CREATE DIRECTORY UTL_FILE_DIR AS '/oracle/backup';

向用目錄物件標識的檔案寫內容:

SQL> declare
  2  fhandle utl_file.file_type;
  3  begin
  4  fhandle := utl_file.fopen('UTL_FILE_DIR', 'example.txt', 'w');
  5  utl_file.put_line(fhandle, 'test write one');
  6  utl_file.put_line(fhandle, 'test write two');
  7  utl_file.fclose(fhandle);
  8  end;
  9  /
PL/SQL procedure successfully completed.

SQL> !
ora10g@vm-vmw4131-t$ more /oracle/backup/example.txt
test write one
test write two

讀取使用目錄物件DIRECTORY標識的檔案內容:
SQL> declare
  2  fhandle utl_file.file_type;
  3  fp_buffer varchar2(4000);
  4  begin
  5  fhandle := utl_file.fopen('UTL_FILE_DIR', 'example.txt', 'R');
  6  utl_file.get_line(fhandle, fp_buffer);
  7  dbms_output.put_line(fp_buffer);
  8  utl_file.get_line(fhandle, fp_buffer);
  9  dbms_output.put_line(fp_buffer);
10  utl_file.fclose(fhandle);
11  end;
12  /
PL/SQL procedure successfully completed.

SQL> /
PL/SQL procedure successfully completed.

此時沒有任何輸出,設定serveroutput:
SQL> set serveroutput on
SQL> /
test write one
test write two
PL/SQL procedure successfully completed.
列印檔案內容。

DIRECTORY的目就在於可以讓我們在Oracle中靈活地對檔案系統中的檔案進行操作。
http://blog.csdn.net/bisal/article/details/24667609

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/90618/viewspace-2061913/,如需轉載,請註明出處,否則將追究法律責任。

相關文章