用BULK INSERT命令導入數據詳解

       如果你從事與數據庫相關的工作,有可能會涉及到將數據從外部數據文件插入倒SQL Server的操作。本文將爲大家演示如何利用BULK INSERT命令來導入數據,並講解怎樣通過改變該命令的一些選項以便更方便且更有效地插入數據。

  BULK INSERT


  在SQL Server中,BULK INSERT是用來將外部文件以一種特定的格式加載到數據庫表的T-SQL命令。該命令使開發人員能夠直接將數據加載到數據庫表中,而不需要使用類似於Integration Services這樣的外部程序。雖然BULK INSERT不允許包含任何複雜的邏輯或轉換,但能夠提供與格式化相關的選項,並告訴我們導入是如何實現的。BULK INSERT有一個使用限制,就是隻能將數據導入SQL Server。

  插入數據下面的例子能讓我們更好的理解如何使用BULK INSERT命令。首先,我們來創建一個名爲Sales的表,我們將要把來自文本文件的數據插入到這個表中。

  CREATE TABLE [dbo].[Sales] 
  ( 
  [SaleID] [int], 
  [Product] [varchar](10) NULL, 
  [SaleDate] [datetime] NULL, 
  [SalePrice] [money] NULL 
  ) 

    當我們使用BULK INSERT命令來插入數據時,不要啓動目標表中的觸發器,因爲觸發器會減緩數據導入的進程。

  在下一個例子中,我們將在Sales表上創建觸發器,用來打印插入到表中的記錄的數量。

  CREATE TRIGGER tr_Sales 
  ON Sales 
  FOR INSERT 
  AS 
  BEGIN 
  PRINT CAST(@@ROWCOUNT AS VARCHAR(5)) + ' rows Inserted.' 
  END 

    這裏我們選擇文本文件作爲源數據文件,文本文件中的值通過逗號分割開。該文件包含1000條記錄,而且其字段和Sales表的字段直接關聯。由於該文本文件中的值是由逗號分割開的,我們只需要指定FIELDTERMINATOR即可。注意,當下面這條語句運行時,我們剛剛創建的觸發器並沒有啓動:

  BULK INSERT Sales FROM 'c:SalesText.txt' WITH (FIELDTERMINATOR = ',')

  當我們要的數據量非常大時,有時候就需要啓動觸發器。下面的腳本使用了FIRE_TRIGGERS選項來指明在目標表上的任何觸發器都應當啓動:

  BULK INSERT Sales FROM 'c:SalesText.txt' WITH (FIELDTERMINATOR = ',', FIRE_TRIGGERS)

  我們可以使用BATCHSIZE指令來設置在單個事務中可以插入到表中的記錄的數量。在前一個例子中,所有的1000條記錄都在同一個事務中被插入到目標表裏。下面的例子,我們將BATCHSIZE參數設置爲2,也就是說要對該表執行500次獨立的插入事務。這也意味着啓動500次觸發器,所以將有500咯打印指令輸出到屏幕上。
BULK INSERT Sales FROM 'c:SalesText.txt' WITH (FIELDTERMINATOR = ',', FIRE_TRIGGERS, BATCHSIZE = 2)

  BULK INSERT不僅僅可以應用於SQL Server 2005的本地映射驅動器。下面的語句將告訴我們如何從名爲FileServer的服務器的D盤中將SalesText文件的數據導入。

  BULK INSERT Sales FROM 'FileServerD$SalesText.txt' WITH (FIELDTERMINATOR = ',')

  有時候,我們在執行導入操作以前,最好能先查看一下將要輸入的數據。下面的語句在使用BULK命令時,使用了OPENROWSET函數,以便從SalesText文本文件中讀取源數據。該語句同時還需要使用一個格式文件(此處沒有列出文件的具體內容)來表明該文本文件中的數據格式。

  SELECT * 
  FROM OPENROWSET(BULK 'c:SalesText.txt' , 
  FORMATFILE='C:SalesFormat.Xml' 
  ) AS mytable; 
  GO 

      


最近做某項目的數據庫分析,要實現對海量數據的導入問題,就是最多把200萬條數據一次導入sqlserver中,如果使用普通的insert語句進行寫出的話,恐怕沒個把小時完不成任務,先是考慮使用bcp,但這是基於命令行的,對用戶來說友好性太差,實際不大可能使用;最後決定使用BULK INSERT語句實現,BULK INSERT也可以實現大數據量的導入,而且可以通過編程實現,界面可以做的非常友好,它的速度也很高:導入100萬條數據不到20秒中,在速度上恐怕無出其右者。
但是使用這種方式也有它的幾個缺點:
1.需要獨佔接受數據的表
2.會產生大量的日誌
3.從中取數據的文件有格式限制
但相對於它的速度來說,這些缺點都是可以克服的,而且你如果願意犧牲一點速度的話,還可以做更精確的控制,甚至可以控制每一行的插入。
對與產生佔用大量空間的日誌的情況,我們可以採取在導入前動態更改數據庫的日誌方式爲大容量日誌記錄恢復模式,這樣就不會記錄日誌了,導入結束後再恢復原來的數據庫日誌記錄方式。
具體的一個語句我們可以這樣寫:

代碼如下:

alter database taxi
set RECOVERY BULK_LOGGED
BULK INSERT taxi..detail FROM 'e:\out.txt'
WITH (
DATAFILETYPE = 'char',
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\n',
TABLOCK
)
alter database taxi
set RECOVERY FULL


這個語句將從e:\out.txt導出數據文件到數據庫taxi的detail表中。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章