ORACLE外部表總結

外部表介紹html

 

ORACLE外部表用來存取數據庫之外的文本文件(Text File)或ORACLE專屬格式文件。所以,創建外部表時不會產生段、區、數據塊等存儲結構,只有與表相關的定義放在數據字典中。外部表,顧名思義,存儲在數據庫外面的表。當存取時才能從ORACLE專屬格式文件中取得數據,外部表僅供查詢,不能對外部表的內容進行修改(INSERT、UPDATE、DELETE操做)。不能對外部表創建索引。由於建立索引就意味着要存在對應的索引記錄。而外部表其實在沒有存儲在數據庫中。故在外部是沒法創建索引的。若是硬要創建的話,則系統會提示「操做在外部組織表上不受支持」的錯誤提示。數據庫

Notice: 外部表是ORACLE 9i後引入的。編程

 

外部表特徵安全

    (1) 位於文件系統之中(必定要在數據庫服務器中,而不是其它網絡路徑),按必定格式分割,服務器

          例如@#$等,文本文件或者其餘類型的文件能夠做爲外部表。網絡

  (2) 對外部表的訪問能夠經過SQL語句來完成,而不須要先將外部表中的數據裝載進數據庫中。oracle

  (3) 外部數據表都是隻讀的,所以在外部表不可以執行DML操做,也不能建立索引。app

  (4) ANALYZE語句不支持採集外部表的統計數據,應該使用DMBS_STATS包來採集外部表的統計數據。測試

  (5) 能夠查詢操做和鏈接。也能夠並行操做。this

  (6) 數據在數據庫的外部組織,是操做系統文件。

  (7) 操做系統文件在數據庫中的標誌是經過一個邏輯目錄來映射的。

 

外部表範例:

 

1:建立目錄對象並受權

從9i開始,ORACLE數據庫若須要存取文件系統,就必須使用目錄對象,以相對路徑方式存取文件,強化數據庫的安全性。創建目錄對象、授予權限。

SQL>CREATE OR REPLACE DIRECTORY DUMP_DIR AS '/oradata/exterltab';

給用戶授予指定目錄的操做權限

SQL>GRANT READ,WRITE ON DIRECTORY DUMP_DIR TO ETL;

 

2:建立外部表

我建立了一個平面文件做爲測試用例,以下所示,總共5條記錄,其中一條錯誤記錄

[oracle@DB-Server exterltab]$ more student.data

10001@#$kerry@#$male@#$28@#$1

10002@#$jimmy@#$male@#$22@#$1

10003@#$ken@#$male@#$21@#$1

10004@#$merry@#$femal@#$20@#$1

this is a bad file

CREATE TABLE EXTER_TEST
(
     ID              NUMBER(5)      ,
     NAME            VARCHAR(12)    ,
     SEX             VARCHAR(8)     ,
     AGE             NUMBER(3)      ,
     GRADE           NUMBER(1)
) ORGANIZATION EXTERNAL
(
            type        oracle_loader
            default directory dump_dir
            access parameters
            (
                    records delimited by newline
                    fields terminated by '@#$'
            )
            location ('student.data')
);

 

外部表語法也是蠻複雜的,參數選項很是多,這裏不作過多解釋。有興趣天然能夠翻閱官方文檔。

 

SQL> select * from exter_test;
select * from exter_test
*
ERROR at line 1:
ORA-29913: error in executing ODCIEXTTABLEFETCH callout
ORA-30653: reject limit reached
ORA-06512: at "SYS.ORACLE_LOADER", line 52

 

出現下面錯誤,是由於student.data文件中有不符合規範的記錄,能夠刪除「this is a bad file」這一條記錄,可是這是爲了測試下面狀況,因此能夠經過執行 alter table exter_test reject limit unlimited;跳過一些限制。

clip_image001

SQL> alter table exter_test reject limit unlimited;
 
Table altered.
 
SQL> select * from exter_test;
 
        ID NAME         SEX             AGE      GRADE
---------- ------------ -------- ---------- ----------
     10001 kerry        male             28          1
     10002 jimmy        male             22          1
     10003 ken          male             21          1
     10004 merry        femal            20          1
 
SQL> 

clip_image002

此時去查看/oradata/exterltab,你會發現自動生成了EXTER_TEST_8907.bad 和 EXTER_TEST_8907.log兩個文件,其中log記錄訪問外部表的記錄信息,bad文件記錄錯誤記錄的信息。大致以下所示

[oracle@DB-Server exterltab]$ ls

EXTER_TEST_8907.bad EXTER_TEST_8907.log student.data

[oracle@DB-Server exterltab]$

clip_image003

 

3:查看外部表的目錄

 

xxx_external_locations 能夠知道當前全部的目錄對象以及相關的外部表,還會查詢出這些外部表所對應的操做系統文件的名字。

select * from all_external_locations;

select * from user_external_locations;

select * from dba_external_locations;

 

 
SQL> show user
USER is "SYS"
SQL> col owner for a20
SQL> col table_name for a30
SQL> col location for a30
SQL> col directory_owner for a3;
SQL> col directory_name for a30;
 
 
SQL> select * from dba_external_locations;
 
 
OWNER          TABLE_NAME               LOCATION           DIR DIRECTORY_NAME
--------- -------------------------- --------------- ---------------------------
SH           SALES_TRANSACTIONS_EXT    sale1v3.dat       SYS DATA_FILE_DIR
ETL          EXTER_TEST                student.data      SYS DUMP_DIR

4:查看外部表的詳細信息

 

 

select * from user_external_tables;
select * from all_external_tables;
select * from dba_external_tables;
 
SQL> desc dba_external_tables;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 OWNER                                     NOT NULL VARCHAR2(30)
 TABLE_NAME                                NOT NULL VARCHAR2(30)
 TYPE_OWNER                                         CHAR(3)
 TYPE_NAME                                 NOT NULL VARCHAR2(30)
 DEFAULT_DIRECTORY_OWNER                            CHAR(3)
 DEFAULT_DIRECTORY_NAME                    NOT NULL VARCHAR2(30)
 REJECT_LIMIT                                       VARCHAR2(40)
 ACCESS_TYPE                                        VARCHAR2(7)
 ACCESS_PARAMETERS                                  VARCHAR2(4000)
 PROPERTY                                           VARCHAR2(10)

 

5:刪除外部表

 

刪除外部表SQL語法跟普通表同樣,可是不一樣之處在於有可能還要刪除與之對應的目錄對象。當外部表不用時,須要及時刪除外部表或者與之對應的目錄對象。不過在刪除這些內容時會有一些限制。這些限制主要是管理上的限制,而不是技術上的限制。也就是說,Oracle數據庫系統沒有對其進行強制的限制。可是若是數據庫管理員不遵照這些限制的話,可能會出現一些問題。如要先刪除外部表,而後再刪除目錄對象。有時候一個目錄對象中可能會包含多個外部表。此時必需要確認全部的外部表都不用了,都已經刪除乾淨了,而後纔可以刪除目錄對象。在建立外部表時,操做系統會判斷一下,與之對應的目錄對象是否已經建立。可是在刪除對象時,系統不會去判斷跟這個目錄對象關聯的外部表是否已經所有刪除。若是目錄對象刪除了,可是還有外部表存在。此時查詢這個外部表的時候,系統就會提示「對象不存在」的錯誤信息。因此這個刪除目錄對象時,數據庫系統缺少一種檢查,此 時只有數據庫管理員在刪除目錄對象時,先手工確認一下這個目錄對象是否存在其餘的外部表。

 

外部表限制

1. 只能對錶進行SELECT,不能進行DELETE、UPDATE、INSERT這些DML操做。

2. 由於外部表須要在ORACLE數據庫「服務端」建立目錄,OS文件必須放在這些目錄中。即這些文件只能放在數據庫服務端。若是數據文件不位於服務器,則沒法使用外部表

3. 外部表上不能建立索引。但能夠創建視圖

4. 外部表不支持LOB對象。若是要使用LOB類型,則不能使用外部表。

eg:刪除外部表的記錄

SQL> delete from exter_test where id=10001;
delete from exter_test where id=10001
            *
ERROR at line 1:
ORA-30657: operation not supported on external organized table

eg: 在外部表上建立視圖

SQL> create or replace view vv
  2  as 
  3  select * from etl.exter_test;
 
View created.
 
SQL> select * from vv;
 
        ID NAME         SEX             AGE      GRADE
---------- ------------ -------- ---------- ----------
     10001 kerry        male             28          1
     10002 jimmy        male             22          1
     10003 ken          male             21          1
     10004 merry        femal            20          1
 
SQL> 

 

外部表優點

若是要談外部表的優點,通常會和SQLLDR來對比,外部表不少語法跟SQLLDR控制文件確實有不少相似的地方,下面談談本身的理解和"Oracel 9i&10g編程藝術"裏面的一些對比

1. SQLLDR須要將數據裝載入庫後才能查詢相關記錄,若是隻是爲了查詢一些記錄,外部表確實比SQLLDR要有優點一些,很方便又不佔用數據庫存儲空間。尤爲是很大的數據,之前作移動綜合分析項目處理SGSN話單(幾百G的數據,若是所有裝載入庫,很是浪費空間和時間)時就有這樣的體會。外部表虛擬的導入過程極快

2:當平面文件改變時,外部表內的數據會跟着改變。這樣避免了插入、更新、刪除等操做,對於超大記錄的外部表至關有優點,我只須要使用Shell命令就能搞定數據庫須要很高代價才能完成的事情。

3:外部表可使用複雜的WHERE 條件有選擇地加載數據。儘管SQLLDR 有一個WHEN 子句用來選擇要加載的行,可是你只能使用AND 表達式和執行相等性比較的表達式,在WHEN 子句中不能使用區間(大於、小於),沒有OR 表達式,也沒有IS NULL 等。

4:可以合併(MERGE)數據。能夠取一個填滿數據的操做系統文件,並由它更新現有的數據庫記錄。

5:能執行高效的代碼查找。能夠將一個外部表聯結到另外一個數據庫表做爲加載過程的一部分。

6:使用INSERT 更容易地執行多表插入。從Oracle9i 開始,經過使用複雜的WHEN 條件,能夠用一個INSERT 語句插入一個或多個表。儘管SQLLDR 也能夠加載到多個表中,可是相應的語法至關複雜。

 

參考資料:

http://blog.itpub.net/22578826/viewspace-703470

http://www.cnblogs.com/lanzi/archive/2010/12/28/1918755.html

http://blog.csdn.net/leshami/article/details/6078481

相關文章
相關標籤/搜索