Oracle 外部表

    Oracle 外部表 

外部表是指不存在於數據庫中的表。經過向Oracle 提供描述外部表的元數據,能夠把一個操做系統文件當成一個只讀的數據庫表,就像這些數據存儲在一個普通數據庫表中同樣來進行訪問。外部表是對數據庫表的延伸。外部表只能在 Oracle 9i 以後  的版本  來使用。sql

Oracle  外部表用來存取數據庫之外的文本文件(Text File )或 Oracle  專屬格式文件。所以,創建外部表時不會產生段、區、數據塊等存儲結構,只有與表相關的定義放在數據字典中。外部表僅供查詢,不能對外部表的內容進行修改(例如INSERT 、 UPDATE 、 DELETE 等操做)。不能在外部表上創建索引。由於建立索引就意味着要存在對應的索引記錄,而其實外部表的數據沒有存儲在數據庫中,故在外部表上是沒法創建索引的。數據庫

外部表使用兩種訪問驅動程序。ORACLE_LOADER 訪問驅動程序只能用於讀取外部表中的表數據並將其載入數據庫。它使用文本文件做爲數據源。 ORACLE_LOADER 訪問驅動程序使用 SQL*Loader 語法來定義外部表。此命令並不建立外部文本文件。 ORACLE_DATAPUMP 訪問驅動程序既能夠將表數據從外部文件載入數據庫中,也能夠將數據從數據庫卸載到外部文件中。它使用二進制文件做爲外部文件。這些二進制文件與 impdp 和 expdp 實用程序所用文件的格式相同,並可與之互換。服務器

若是外部表採用PARALLEL 的方式加載的話,那麼加載的數據是無序的。因此,這種狀況須要綜合考慮,尤爲是在使用該方式來查看告警日誌文件內容的時候須要特別注意。oracle

外部表有以下幾點特性:app

①   外部表的數據  位於文件系統之中,  並  按必定格式分割  。  文本文件或者  其它  類型的表能夠做爲外部表。  操做系統文件在數據庫中的標誌是經過一個邏輯目錄來映射的,因此外部表須要在Oracle 數據庫「服務端」建立目錄,這些 OS 文件必須放在這些目錄中。ide

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

③   外部表是隻讀的,所以,  只能對  外部  表進行SELECT 操做,  不能  對  外部表執行DML  (DELETE 、 UPDATE 和 INSERT 等)  操做,也不能建立索引  ,  可是能夠建立視圖,也能夠建立同義詞。this

④  ANALYZE 語句不支持採集外部表的統計數據,應該使用 DMBS_STATS 包來採集外部表的統計數據。spa

⑤   能夠對外部表執行查詢、鏈接和並行操做。操作系統

⑥   外部表不支持LOB 對象。

⑦   從Oracle 12.2 開始支持外部表分區的功能。

與外部表相關的幾個視圖   以下所示   :

 

SELECT       *       FROM       DBA_EXTERNAL_LOCATIONS;       --描述外部表的位置

SELECT       *       FROM       DBA_EXTERNAL_TABLES;      --全部的外部表

SELECT       *       FROM       DBA_DIRECTORIES;      --數據庫中全部的目錄對象

有關外部表的一個使用示例以下所示:

CREATE       DIRECTORY   EXT_LOG        AS       '/u01/app/oracle/ext_log'      ;

DROP       TABLE       ALERT_LOG;

CREATE       TABLE       ALERT_LOG( 

        TEXT VARCHAR2(4000) 

        )

ORGANIZATION EXTERNAL 

        (TYPE   ORACLE_LOADER

         DEFAULT       DIRECTORY EXT_LOG 

         ACCESS PARAMETERS 

        (RECORDS DELIMITED       BY       NEWLINE ) LOCATION (      'log.xml'      ) 

);

上邊的SQL語句建立了一個外部表,執行下面的SQL語句就能夠查看文件/u01/app/oracle/ext_log/log.xml的內容了。

SELECT       *       FROM       ALERT_LOG;

須要注意的是,若是外部表對應的文件中包含中文,那麼須要設置正確的外部表的字符集。設置方法爲在「RECORDS DELIMITED BY NEWLINE」的後邊加上外部文件的字符集:

RECORDS DELIMITED       BY       NEWLINE CHARACTERSET utf8

&    說明:

有關外部表及外部表的使用更多內容介紹能夠參考個人 BLOG  : http://blog.itpub.net/26736162/viewspace-2140135/ 、 http://blog.itpub.net/26736162/viewspace-1221559/

真題一、 Which  two operations can be performed on an external table? (Choose two.)

A 、 Create a view on the table.

B 、 Create an index on the table.

C 、 Create a synonym on the table.

D 、 Add a virtual column to the table.

E 、 Update the table using the UPDATE statement.

F 、 Delete rows in the table using the DELETE command.

答案:A 、 C 。

題目問的是哪兩個操做能夠在外部表上執行,根據本小節的內容能夠知道,  在外部表上能夠建立視圖,能夠建立同義詞,但不能建立索引,不能添加列  ,  不能執行DML 語句,因此,本題的答案爲 A 和 C 。







--=================

-- Oracle  外部表

--=================

 

     外部表只能在Oracle 9i 以後來使用。簡單地說,外部表,是指不存在於數據庫中的表。經過向Oracle提供描述外部表的元數據,咱們

能夠把一個操做系統文件當成一個只讀的數據庫表,就像這些數據存儲在一個普通數據庫表中同樣來進行訪問。外部表是對數據庫表的延伸。

 

1、外部表的特性

     位於文件系統之中,按必定格式分割,如文本文件或者其餘類型的表能夠做爲外部表。

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

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

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

 

2、建立外部表的注意事項

    1. 須要先創建目錄對象

 

    2. 對於操做系統文件的要求

         文件要有固定的格式、不能有標題列、訪問時會自動建立一個日誌文件

 

    3. 在創建臨時表時的相關限制

         對錶中字段的名稱存在特殊字符的狀況下,必須使用英文狀態的下的雙引號將該表列名稱鏈接起來。如採用」SalseID#」。

         對於列名字中特殊符號未採用雙引號括起來時,會致使沒法正常查詢數據。

         建議不用使用特殊的列標題字符

 

         在建立外部表的時候,並無在數據庫中建立表,也不會爲外部表分配任何的存儲空間。

         建立外部表只是在數據字典中建立了外部表的元數據,以便對應訪問外部表中的數據,而不在數據庫中存儲外部表的數據。

         簡單地說,數據庫存儲的只是與外部文件的一種對應關係,如字段與字段的對應關係。而沒有存儲實際的數據。

         因爲存儲實際數據,故沒法爲外部表建立索引,同時在數據使用DML時也不支持對外部表的插入、更新、刪除等操做。

 

    4. 刪除外部表或者目錄對象

         通常狀況下,先刪除外部表,而後再刪除目錄對象,若是目錄對象中有多個表,應刪除全部表以後再刪除目錄對象。

         若是在未刪除外部表的狀況下,強制刪除了目錄,在查詢到被刪除的外部表時,將收到"對象不存在"的錯誤信息。

         查詢dba_external_locations來得到當前全部的目錄對象以及相關的外部表,同時會給出這些外部表所對應的操做系統文件的名字。

           

    5. 對於操做系統平臺的限制

         不一樣的操做系統對於外部表有不一樣的解釋和顯示方式

         如在Linux操做系統中建立的文件是分號分隔且每行一條記錄,但該文件在Windows操做系統上打開則並不是如此。

         建議避免不一樣操做系統以及不一樣字符集所帶來的影響

 

3、建立外部表

     使用CREATE TABLE語句的ORGANIZATION EXTENERAL子句來建立外部表。外部表不分配任何盤區,由於僅僅是在數據字典中建立元數據。

    1. 外部表的建立語法

         create  table table_name

             (col1 datatype1 ,col2 datatype2  ,col3 datatype3 )

             organization exteneral

             (.....)

           

    2. 由查詢結果集,使用Oracle_datapump來填充數據來生成外部表

        a . 建立系統目錄以及Oracle數據目錄名來創建對應關係,同時授予權限

            [oracle@oradb ~]$ mkdir  -p  /home /oracle /external_tb /data

       

            sys@ORCL >  create  or  replace directory dat_dir  as  '/home/oracle/external_tb/data/' ;

 

            sys@ORCL >  grant  read ,write  on directory dat_dir  to scott ;

 

        b . 建立外部表

 

            scott@ORCL >  create  table ex_tb1    -- 建立外部表

              2   (ename ,job ,sal ,dname )         -- 表列描述,注意未指定數據類型

              3  organization  external

              4   (

              5     type oracle_datapump        -- 使用datapump將查詢結果填充到外部表,注,此處由select生成,故不支持oracle_loader

              6     default directory dat_dir   -- 指定外部表的存放目錄

              7    location ( 'tb1.exp' , 'tb2.exp' )   -- 產生外部表的內容將填充到這些文件中

              8   )

              9    parallel                        -- 按並行方式來填充

             10   as

             11     select ename ,job ,sal ,dname      - 填充使用的原始數據

             12     from emp  join dept

             13       on emp .deptno =dept .deptno ;

 

        c . -- 驗證外部表

            scott@ORCL >  select  *  from ex_tb1 ;

 

            ENAME      JOB              SAL DNAME

             ---------- --------- ---------- --------------

            SMITH      CLERK            800 RESEARCH

            ALLEN      SALESMAN        1600 SALES

            WARD       SALESMAN        1250 SALES

            JONES      MANAGER         2975 RESEARCH

                      ..........

       

             對於使用上述方式建立的外部表能夠將其複製到其餘路徑做爲外部表的原始數據來生成新的外部表,用於轉移數據。

           

    3. 使用SQLLDR提供外部表的定義並建立外部表

         關於SQL *Loader的使用請參照: SQL*Loader使用方法

         咱們使用SQL *Loader和下面的這個控制文件來生成外部表的定義

            [oracle@oradb ~]$ cat demo1 .ctl

             LOAD DATA

            INFILE  *

             INTO  TABLE DEPT_NEW

            FIELDS TERMINATED  BY  ','

             (DEPTNO , DNAME , LOC  )

            BEGINDATA

            10 ,Sales ,Virginia

            20 ,Accounting ,Virginia

            30 ,Consulting ,Virginia

            40 ,Finance ,Virginia

                       

            [oracle@oradb ~]$ sqlldr scott /tiger  control =demo1 .ctl external_table =generate_only

 

        EXTERNAL_TABLE  參數有如下三個值:

            NOT_USED :默認值。

             EXECUTE :這個值說明SQLLDR不會生成並執行一個SQL  INSERT語句;而是會建立一個外部表,且使用一個批量SQL語句來加載。

            GENERATE_ONLY :使SQLLDR 並不具體加載任何數據,而只是會生成所執行的SQL DDL 和DML 語句,並放到它建立的日誌文件中。

   

         注:DIRECT =TRUE 覆蓋EXTENAL_TABLE =GENERATE_ONLY。若是指定了DIRECT =TRUE,則會加載數據,而不會生成外部表。

 

        [oracle@oradb ~]$ cat demo1 . log     -- 查看sqlldr產生的日誌文件

 

         Table DEPT_NEW , loaded  from every logical record .

         Insert  option  in effect  for this  table :  INSERT

 

            Column  Name                  Position    Len  Term Encl Datatype

         ------------------------------ ---------- ----- ---- ---- ---------------------

        DEPTNO                              FIRST      *    ,       CHARACTER           

        DNAME                                NEXT      *    ,       CHARACTER           

        LOC                                  NEXT      *    ,       CHARACTER           

 

         CREATE DIRECTORY statements needed  for files    -- 建立一個目錄

         ------------------------------------------------------------------------

         CREATE DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000  AS  '/home/oracle/'

 

         CREATE  TABLE statement  for  external  table :      -- 生成建立外部表的命令

         ------------------------------------------------------------------------

         CREATE  TABLE "SYS_SQLLDR_X_EXT_DEPT_NEW"

         (

          "DEPTNO" NUMBER (2 ),

          "DNAME" VARCHAR2 (20 ),

          "LOC" VARCHAR2 (20 )

         )

        ORGANIZATION  external                  -- 該子句代表是一個外部表 heap 對應普通表,index 對應iot,external 對應外部表

         (

           TYPE oracle_loader                   -- 說明外部文件訪問方式:oracle_loader或oracle_datapump(9i不支持)

           DEFAULT DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000    -- 指定外部文件的缺省目錄

          ACCESS PARAMETERS                               -- 這個訪問參數有些相似於sqlldr中控制文件中的描述信息

           (                                              -- 系統根據這些描述信息來生成外部表的格式

            RECORDS DELIMITED  BY NEWLINE CHARACTERSET US7ASCII     -- 記錄默認以換行符結束

            BADFILE  'SYS_SQLLDR_XT_TMPDIR_00000' : 'demo1.bad'       -- 存放處理失敗的記錄文件描述

            LOGFILE  'demo1.log_xt'                                 -- 日誌文件

            READSIZE 1048576  --Oracle 讀取輸入數據文件所用的默認緩衝區,此處爲MB,如專用模式則從PGA分配,如共享模式則從SGA分配

            SKIP 6                                        -- 跳過的記錄數,由於咱們使用了控制文件,因此前面的控制信息須要跳過

            FIELDS TERMINATED  BY "," LDRTRIM              -- 描述字段的終止符

            REJECT ROWS  WITH  ALL  NULL FIELDS              -- 全部爲空值的行被跳過而且記錄到bad file.

             (                                             -- 下面是描述外部文件各個列的定義

              "DEPTNO"  CHAR (255 )

                TERMINATED  BY "," ,

              "DNAME"  CHAR (255 )

                TERMINATED  BY "," ,

              "LOC"  CHAR (255 )

                TERMINATED  BY ","

             )

           )

          location

           (

             'demo1.ctl'                                 -- 描述外部文件的文件名

           )

         )REJECT LIMIT UNLIMITED                         -- 描述容許的錯誤數,此處爲無限制

 

         INSERT statements used  to  load internal tables :              -- 用於將數據填充到表,使用append方式

         ------------------------------------------------------------------------

         INSERT  /*+ append */  INTO DEPT_NEW

         (

          DEPTNO ,

          DNAME ,

          LOC

         )

         SELECT

          "DEPTNO" ,

          "DNAME" ,

          "LOC"

         FROM "SYS_SQLLDR_X_EXT_DEPT"

 

        statements  to cleanup objects created  by previous statements :     -- 用於刪除目錄和外部表的定義信息

         ------------------------------------------------------------------------

         DROP  TABLE "SYS_SQLLDR_X_EXT_DEPT_NEW"

         DROP DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000

 

     -----------------------------------------------------------------------------------------------------------------------

        sys@ORCL >  grant  create  any directory  to scott ;

 

        sys@ORCL >  grant  drop  any directory  to scott ;

 

        scott@ORCL >  create  table dept_new

          2   (deptno number ,dname varchar2 (20 ),loc varchar2 (25 ));

 

        scott@ORCL >  select  *  from dept_new ;

 

         no rows selected

       

        [oracle@oradb ~]$ sqlldr scott /tiger control =demo1 .ctl external_table = execute

 

        scott@ORCL >  select  *  from dept_new ;

 

            DEPTNO DNAME                LOC

         ---------- -------------------- -------------------------

                10 Sales                Virginia

                20 Accounting           Virginia

                30 Consulting           Virginia

                40 Finance              Virginia

 

    4. 使用平面文件定義並生成外部表

        a . 平面文件數據

            1.dat  :

                7369 ,SMITH ,CLERK ,7902 ,17 -DEC -80 ,100 ,0 ,20

                7499 ,ALLEN ,SALESMAN ,7698 ,20 -FEB -81 ,250 ,0 ,30

                7521 ,WARD ,SALESMAN ,7698 ,22 -FEB -81 ,450 ,0 ,30

                7566 ,JONES ,MANAGER ,7839 ,02 -APR -81 ,1150 ,0 ,20

 

            2.dat  :

                7654 ,MARTIN ,SALESMAN ,7698 ,28 -SEP -81 ,1250 ,0 ,30

                7698 ,BLAKE ,MANAGER ,7839 ,01 -MAY -81 ,1550 ,0 ,30

                7934 ,MILLER ,CLERK ,7782 ,23 -JAN -82 ,3500 ,0 ,10

 

        b . 繼續使用前面建立的目錄 /home /oracle /external_tb /data 來存放數據文件:

 

            sys@ORCL >  select  *  from dba_directories ;

 

            OWNER           DIRECTORY_NAME  DIRECTORY_PATH

             --------------- --------------- ---------------------------------------------

            SYS             DATA_PUMP_DIR    /u01 /oracle /10g /rdbms / log /

            SYS             DAT_DIR          /home /oracle /external_tb /data /

           

            scott@ORCL > ho ls  /home /oracle /external_tb /data /

            1.dat  2.dat  tb1 . exp  tb2 . exp

           

        c . 建立外部表

            scott@ORCL >  get  /u01 /bk /scripts /tb .emp_new

              1   create  table emp_new

              2   (

              3      emp_id number (4 ),

              4      ename varchar2 (15 ),

              5      job varchar2 (12 )  ,

              6      mgr_id number (4 )  ,

              7      hiredate date ,

              8      salary number (8 ),

              9      comm number (8 ),

             10      dept_id number (2 )

             11   )

             12  organization  external

             13   (

             14       type oracle_loader

             15       default directory dat_dir

             16      access parameters

             17     (

             18        records delimited  by newline

             19        fields terminated  by  ','

             20     )

             21  location

             22       ( '1.dat' , '2.dat' )

             23 *  );

             

             scott@ORCL > start  /u01 /bk /scripts /tb .emp_new

 

        d . 驗證外部表  

            scott@ORCL >  select  *  from emp_new ;

 

                EMP_ID ENAME           JOB              MGR_ID HIREDATE      SALARY      COMM    DEPT_ID

             ---------- --------------- ------------ ---------- --------- ---------- ---------- ----------

                  7369 SMITH           CLERK              7902 17 -DEC -80       100          0         20

                  7499 ALLEN           SALESMAN           7698 20 -FEB -81       250          0         30

                                      ............................

               

            scott@ORCL >  delete  from emp_new  where ename = 'SMITH' ;    -- 外部表不能執行DML

             delete  from emp_new  where ename = 'SMITH'

                         *

            ERROR at line 1 :

            ORA -30657 : operation  not supported  on  external organized  table

           

            scott@ORCL >  insert  into emp_new (emp_id ,ename )  select 8888 , 'Robinson'  from dual ;

             insert  into emp_new (emp_id ,ename )  select 8888 , 'Robinson'  from dual

                         *

            ERROR at line 1 :

            ORA -30657 : operation  not supported  on  external organized  table

                                       

      e .得到外部表的有關信息:

            scott@ORCL > col access_parameters format a35

            scott@ORCL >  select owner ,table_name ,type_name ,default_directory_name ,access_parameters

              2   from dba_external_tables ;

 

            OWNER      TABLE_NAME      TYPE_NAME                      DEFAULT_DIRECTO ACCESS_PARAMETERS

             ---------- --------------- ------------------------------ --------------- -----------------------------------

            SCOTT      EX_TB1          ORACLE_DATAPUMP                DAT_DIR

            SCOTT      EMP_NEW         ORACLE_LOADER                  DAT_DIR         records delimited  by newline

                                                                                           fields terminated  by  ','

 

 

            SCOTT      EMP_PUMP        ORACLE_DATAPUMP                DAT_DIR         records delimited  by newline

                                                                                           fields terminated  by  ','

  

      f .得到平面文件的位置,使用以下的查詢:

            scott@ORCL >  select  *  from dba_external_locations  order  by table_name ;

 

            OWNER      TABLE_NAME      LOCATION        DIR DIRECTORY_NAME

             ---------- --------------- --------------- --- ------------------------------

            SCOTT      EMP_NEW         1.dat           SYS DAT_DIR

            SCOTT      EMP_NEW         2.dat           SYS DAT_DIR

            SCOTT      EMP_PUMP        1.dat           SYS DAT_DIR

            SCOTT      EMP_PUMP        2.dat           SYS DAT_DIR

            SCOTT      EX_TB1          tb2 . exp         SYS DAT_DIR

            SCOTT      EX_TB1          tb1 . exp         SYS DAT_DIR     

               

    5. 外部表定義的進一步分析

         CREATE  TABLE external_table

          (

            COL01 VARCHAR2 (100 ),

                COL02 NUMBER ,

                  ......

          )

        ORGANIZATION  EXTERNAL

         (

             TYPE ORACLE_LOADER

             DEFAULT DIRECTORY "XXX"

            ACCESS PARAMETERS

                 (

                RECORDS DELIMITED  BY 0X '0A'

                SKIP 1

                BADFILE  'bad.txt'

                FIELDS TERMINATED  BY  ','

                OPTIONALLY ENCLOSED  BY  '"'

                LRTRIM MISSING FIELD  VALUES ARE  NULL

                REJECT ROWS  WITH  ALL  NULL FIELDS

                 )

            LOCATION

                 ("CJ_DIR" : 'data.txt' )

         )REJECT LIMIT UNLIMITED ;

 

         外部表定義的幾個重點

            a .ORGANIZATION  EXTERNAL  關鍵字,必需要有。以代表定義的表爲外部表。

            b . 重要參數外部表的類型

                ORACLE_LOADER  :定義外部表的缺省方式,只能只讀方式實現文本數據的裝載。

                ORACLE_DATAPUMP  :支持對數據的裝載與卸載,數據文件必須爲二進制 dump文件。能夠從外部表提取數據裝載到內部表,也

                     能夠從內部表卸載數據做爲二進制文件填充到外部表。

            c . DEFAULT DIRECTORY  :缺省的目錄指明瞭外部文件所在的路徑

            d .LOCATION  :定義了外部表的位置

            f .ACCESS PARAMETERS  :描述如何對外部表進行訪問

                RECORDS 關鍵字後定義如何識別數據行  

                    DELIMITED  BY  'XXX' —— 換行符,經常使用newline定義換行,並指明字符集。對於特殊的字符則須要單獨定義,

                         如特殊符號,可使用OX ' 十六位值',例如tab (/t )的十六位是9,則DELIMITED  BY 0X '09';

                        cr (/r ) 的十六位是d,那麼就是DELIMITED  BY 0X '0D'。

                    SKIP X —— 跳過X行數據,有些文件中第一行是列名,須要跳過第一行,則使用SKIP 1。

                   

                FIELDS 關鍵字後定義如何識別字段,經常使用的以下:

                    FIELDS :TERMINATED  BY  'x' ——字段分割符。

                    ENCLOSED  BY  'x' —— 字段引用符,包含在此符號內的數據都當成一個字段。

                     例如一行數據格式如:"abc" ,"a""b,""c,"。使用參數TERMINATED  BY  ',' ENCLOSED  BY  '"'後,系統會讀到兩個字段,

                         第一個字段的值是abc,第二個字段值是a"b,"c ,。

                    LRTRIM —— 刪除首尾空白字符。

                    MISSING FIELD  VALUES ARE  NULL —— 某些字段空缺值都設爲 NULL。

 

                     對於字段長度和分割符不肯定且準備用做外部表文件,可使用UltraEdit、Editplus等來進行分析測試,若是文件較

                     大,則須要考慮將文件分割成小文件並從中提取數據進行測試。

       

         外部表對錯誤的處理

            REJECT LIMIT UNLIMITED

                 在建立外部表時最後加入LIMIT子句,表示能夠容許錯誤的發生個數。默認值爲零。設定爲UNLIMITED則錯誤不受限制

            BADFILE  和NOBADFILE 子句

                 用於指定將捕獲到的轉換錯誤存放到哪一個文件。若是指定了NOBADFILE則表示忽略轉換期間的錯誤

                 若是未指定該參數,則系統自動在源目錄下生成與外部表同名的 .BAD文件

                BADFILE 記錄本次操做的結果,下次將會被覆蓋

            LOGFILE  和NOLOGFILE 子句

                 一樣在accessparameters中加入LOGFILE  'LOG_FILE.log'子句,則全部Oracle的錯誤信息放入 'LOG_FILE.log'中

                 而NOLOGFILE子句則表示不記錄錯誤信息到 log中,如忽略該子句,系統自動在源目錄下生成與外部表同名的 . LOG文件

 

         注意如下幾個常見的問題

            1. 外部表常常遇到BUFFER不足的狀況,所以儘量的增大 READ  SIZE

            2. 換行符不對產生的問題。在不一樣的操做系統中換行符的表示方法不同,碰到錯誤日誌提示如是換行符問題,可使用

                UltraEdit 打開,直接看十六進制

            3. 特定行報錯時,查看帶有"BAD"的日誌文件 ,其中保存了出錯的數據 ,用記事本打開看看那裏出錯 ,是否存在於外部表定義相沖突

           




                 

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

外部表特徵

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

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

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

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

外部表範例:

1:建立目錄對象並受權

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

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

2:建立外部表

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

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

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

                 

                 

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_image002

[oracle@DB-Server exterltab]$ ls

[oracle@DB-Server exterltab]$

                 

                 

select * from all_external_locations;

select * from dba_external_locations;

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數據庫系統沒有對其進行強制的限制。可是若是數據庫管理員不遵照這些限制的話,可能會出現一些問題。如要先刪除外部表,而後再刪除目錄對象。有時候一個目錄對象中可能會包含多個外部表。此時必需要確認全部的外部表都不用了,都已經刪除乾淨了,而後纔可以刪除目錄對象。在建立外部表時,操做系統會判斷一下,與之對應的目錄對象是否已經建立。可是在刪除對象時,系統不會去判斷跟這個目錄對象關聯的外部表是否已經所有刪除。若是目錄對象刪除了,可是還有外部表存在。此時查詢這個外部表的時候,系統就會提示「對象不存在」的錯誤信息。因此這個刪除目錄對象時,數據庫系統缺少一種檢查,此 時只有數據庫管理員在刪除目錄對象時,先手工確認一下這個目錄對象是否存在其餘的外部表。

外部表限制:

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

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

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>

 

外部表優點:

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

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

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

相關文章
相關標籤/搜索