Oracle Directory文件夾的知識


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

MOS上對DIRECTORY的解釋(266875.1):

(1)、基於服務端 vs 基於client

DIRECTORY變量指出了expdp導出數據泵或impdp導入數據泵將dump文件、log文件以及SQL文件(僅適用於impdp)寫到什么路徑。

由於導出數據泵和導入數據泵都是基於服務端的,不是基於client的,因此輸出文件的路徑都是相對於服務端文件夾的路徑。數據泵要求將文件夾路徑作為一個文件夾對象。一個文件夾對象將文件系統的一個文件夾路徑映射為一個名稱。

(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將會使用。環境變量是在在執行導出和導入數據泵應用的client系統中使用操作系統命令定義的,分配給基於client環境變量的取值必須和基於服務端的文件夾對象一致,且必須首先在server端建立

文件夾MY_DIR中創建dump文件和MY_DIR_LOG中創建日志文件的演示樣例:

在使用expdp的client機器上,設定環境變量:

-- 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角色),那么數據泵試圖使用默認的基於server端的文件夾對象,DATA_PUMP_DIR。理解數據泵不會創建DATA_PUMP_DIR文件夾對象是很重要的。僅當授權用戶未使用不論什么之前提到的機制創建的文件夾對象時。才會嘗試使用DATA_PUMP_DIR。

這個默認的文件夾對象必須首先由DBA創建。不要將這個和同名的基於client的環境變量相混淆。

首先,清空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中靈活地對文件系統中的文件進行操作。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM