天天看點

sqlPlus導入.csv檔案資料(建外部表)

有關CSV檔案的介紹見https://baike.so.com/doc/5126285-5355574.html ,如果您對CSV有一定了解,請直接往下看!

因為PL/SQL連接配接oracle出了些問題,至今沒有解決,眼看要交作業了,就先用sqlplus來導入資料了,

如果用PL/SQL如何導入,請見其他博友的文章:https://blog.csdn.net/ShenJiancomputer/article/details/8112088

以下是通過外部表來實作在sqlplus中導入資料的内容:

首先總結下步驟:

1、準備一個外部檔案,這裡放的是我們需要插入表中的資料(建議先備份,以免資料被破壞,我就碰到這樣的問題)說明:我的外部檔案格式為 以逗号分隔的csv檔案,當然,你也可以儲存為其他格式的,但是在建立外部表的時候就要對應好了。(或者不是這種格式的可以在Excel->另存為那裡修改)

sqlPlus導入.csv檔案資料(建外部表)

2、建立目錄對象,第一步的外部檔案就放在這個目錄下(目前使用者若無建立目錄對象的權限,請先授權,具體方法請往下看)

3、建立一個外部表,用于讀取外部表中的資料(在建立外部表時,字段的數量、各個字段的資料類型都要與外部檔案中的資料格式一一對應;并且不能為表中的各個字段指定主鍵限制、unique限制、not null限制等。外部表是個隻讀表,隻能讀取外部檔案、不能向外部表添加、更新和删除資料、也不能在外部表上建立索引)。

4、用 select * from 外部表名 查詢外部表中的資料

5、建立一個内部表,這個就是在資料庫中我們需要建立的表,直接将外部表中的資料複制到内部表中,這樣便将外部檔案中的資料插入到資料庫并可以對它進行增删查改了(複制時注意外部表和内部表的列以及類型、長度的對應關系!)

在開始前需強調的是:外部表不要加任何限制(主鍵、外鍵、唯一限制等全都不行),否則會報錯:

sqlPlus導入.csv檔案資料(建外部表)

1.我們需要一個外部檔案db_student.csv,這裡放着我們要導入的資料,部分内容如下(資料是老師給的,我也不知道涉不涉及别人的隐私,統一打一下碼吧)

sqlPlus導入.csv檔案資料(建外部表)

2.建立一個目錄對象

 CREATE OR REPLACE DIRECTORY external_student AS 'D:\oraclefinalexam\external';

external_student  :檔案系統目錄D:\oraclefinalexam\external的别名,這是我們要通路的資料檔案db_student所在的目錄

sqlPlus導入.csv檔案資料(建外部表)

好吧,權限不夠,我們連接配接到system使用者,為staffuser(目前使用者)授權

怎麼授權呢?這還得問oracle

 select distinct privilege from dba_sys_privs where privilege like '%DIRECTORY%';
sqlPlus導入.csv檔案資料(建外部表)

第一項是删除目錄的,第二項是建立目錄的,現在就來授予staffuser使用者建立目錄的權限(可以順便把删除目錄的也給了):

sqlPlus導入.csv檔案資料(建外部表)

回到staffuser使用者,接着建立目錄對象

sqlPlus導入.csv檔案資料(建外部表)

3.建立外部表:

建表之前得先看下我們的資料呀

sqlPlus導入.csv檔案資料(建外部表)

第一列為學号eg:

sqlPlus導入.csv檔案資料(建外部表)

     第二列專業編号   第三列姓名

第四列性别,第五列出生日期,第六列為空列,對應班級号

第七列家庭住址,第八列郵政編碼,第九列通訊位址

第十列電話,第十一列應該是郵箱位址的,檔案中沒有給出

然後對照一下我預先在oracle中建好的表有哪些字段(我們稱之為内部表吧)

sqlPlus導入.csv檔案資料(建外部表)

接着我們來建立外部表:

sqlPlus導入.csv檔案資料(建外部表)
sqlPlus導入.csv檔案資料(建外部表)

預設情況下,允許出現的錯誤個數為0,是以錯誤内容為“以達到拒絕限制值”

在将源資料檔案中的資料類型轉換為表定義的列資料類型的時候,有時候會出現錯誤,例如指定的分隔符不符合要求(eg:在外部檔案中的字段分隔符為英文逗号(,),而建立外部表的時候卻指定分隔符為中文逗号,這就會導緻資料類型出錯,在建立外部表時,可以指定一些子句來對外部表進行處理,如reject limit,badfile(或 nobadfile),logfile(或nologfile)等)

解決方法:在末尾加一句 REJECT LIMIT UNLIMITED; 

sqlPlus導入.csv檔案資料(建外部表)
CREATE TABLE ext_student (
	register_no VARCHAR2(12),
	major_no VARCHAR2(10), --db_major的外鍵
	s_name CHAR(8),
	s_gender CHAR(2),
	s_dateofbirth DATE,
	s_class NUMBER(1),
	s_address VARCHAR2(50),
	s_postcode VARCHAR2(6),
	s_mail_address VARCHAR2(50),
	s_tele VARCHAR2(15)
	--s_email VARCHAR2(30) 
) ORGANIZATION EXTERNAL (
	TYPE oracle_loader
	DEFAULT DIRECTORY external_student
	ACCESS PARAMETERS (
		FIELDS TERMINATED BY ','
		MISSING FIELD VALUES ARE null)
		LOCATION('db_student.csv') 
) REJECT LIMIT UNLIMITED; 
           

4.使用select語句查詢外部表中的資料:

sqlPlus導入.csv檔案資料(建外部表)

emmmmm,雖然不再提示錯誤,但是傳回0行資料,這是因為雖然不限制可以出現錯誤的個數,但如果資料類型轉換失敗,源檔案資料還是無法被讀取到表的相應列中;

在我們資料中,日期格式如下,我們建表時用的是DATE類型,但是oracle對插入DATE類型的資料格式有嚴格要求https://blog.csdn.net/beyondlpf/article/details/6959139,這樣是無法直接插進去的,我的解決方法是修改資料類型

sqlPlus導入.csv檔案資料(建外部表)

修改字段類型DATE為VARCHAR2,長度20

sqlPlus導入.csv檔案資料(建外部表)

把内部表的也改一下:

sqlPlus導入.csv檔案資料(建外部表)
sqlPlus導入.csv檔案資料(建外部表)

依然還是未標明行?因為我的學号的長度為12,但是我們外部檔案的學号這一列中,每一個值都多了一個空格,是以長度應該為13

sqlPlus導入.csv檔案資料(建外部表)

修改長度(内部表可以不改,複制資料的時候直接用trim函數去掉空格即可)

sqlPlus導入.csv檔案資料(建外部表)

看下這回還會有啥問題:

sqlPlus導入.csv檔案資料(建外部表)

資料是出來了,但是不太好看,用set linesize 1000  設定一下每行輸出字元數為1000 (自己覺得舒服就行),再來查:

sqlPlus導入.csv檔案資料(建外部表)

5.OK,接下來要考慮如何将這些資料複制到内部表裡面了!

--db_student是内部表,是一個待插入資料的空表

--ext_student是我們的外部表,這裡放的是我們要複制到db_student中的資料

insert  into db_student (register_no,major_no,s_name,s_gender,s_dateofbirth,s_class,s_address,s_postcode,s_mail_address,s_tele)

select trim(register_no),major_no,s_name,s_gender,s_dateofbirth,s_class,s_address,s_postcode,s_mail_address,s_tele from ext_student ;

報錯:

ORA-29913: 執行 ODCIEXTTABLEFETCH 調出時出錯

ORA-00001: 違反唯一限制條件 (STAFFUSER.SYS_C0011113)

打開CSV檔案發現有大量重複資料,可能資料被破壞了,重新複制一份源資料進來,覆寫掉它

sqlPlus導入.csv檔案資料(建外部表)
sqlPlus導入.csv檔案資料(建外部表)
sqlPlus導入.csv檔案資料(建外部表)

完成!