日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

BCP导出导入大容量数据实践

發(fā)布時(shí)間:2025/3/20 76 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BCP导出导入大容量数据实践 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

SQL SERVER提供多種不同的數(shù)據(jù)導(dǎo)出導(dǎo)入的工具,也可以編寫SQL腳本,使用存儲(chǔ)過(guò)程,生成所需的數(shù)據(jù)文件,甚至可以生成包含SQL語(yǔ)句和數(shù)據(jù)的腳本文 件。各有優(yōu)缺點(diǎn),以適用不同的需求。下面介紹大容量數(shù)據(jù)導(dǎo)出導(dǎo)入的利器——BCP實(shí)用工具。同時(shí)在后面也介紹BULK INSERT導(dǎo)入大容量數(shù)據(jù),以及BCP結(jié)合BULK INSERT做數(shù)據(jù)接口的實(shí)踐(在SQL2008R2上實(shí)踐)。


1. BCP的用法

BCP 實(shí)用工具可以在 Microsoft SQL Server 實(shí)例和用戶指定格式的數(shù)據(jù)文件間大容量復(fù)制數(shù)據(jù)。使用 BCP實(shí)用工具可以將大量新行導(dǎo)入 SQL Server 表,或?qū)⒈頂?shù)據(jù)導(dǎo)入數(shù)據(jù)文件。除非與 queryout 選項(xiàng)一起使用,否則使用該實(shí)用工具不需要了解 Transact-SQL 知識(shí)。BCP既可以在CMD提示符下運(yùn)行,也可以在SSMS下執(zhí)行。


figure-1

bcp?{[[database_name.][schema].]{table_name?|?view_name}?|?"query"}{in?|?out?|?queryout?|?format}?data_file[-mmax_errors]?[-fformat_file]?[-x]?[-eerr_file][-Ffirst_row]?[-Llast_row]?[-bbatch_size][-ddatabase_name]?[-n]?[-c]?[-N]?[-w]?[-V?(70?|?80?|?90?)]?[-q]?[-C?{?ACP?|?OEM?|?RAW?|?code_page?}?]?[-tfield_term]?[-rrow_term]?[-iinput_file]?[-ooutput_file]?[-apacket_size][-S?[server_name[\instance_name]]]?[-Ulogin_id]?[-Ppassword][-T]?[-v]?[-R]?[-k]?[-E]?[-h"hint?[,...n]"]


簡(jiǎn)單的導(dǎo)出例子1:

figure-2

?

簡(jiǎn)單的導(dǎo)出例子2:

figure-3


在SSMS上同時(shí)也可以執(zhí)行:

EXEC?[master]..xp_cmdshell'BCP?TestDB_2005.dbo.T1?out?E:\T1_02.txt?-c?-T'GO

code-1


?

figure-4

?

?

EXEC?[master]..xp_cmdshell'BCP?"SELECT?*?FROM?TestDB_2005.dbo.T1"?queryout?E:\T1_03.txt?-c?-T' GO

code-2

?
?

figure-5

?

從個(gè)人來(lái)講,我更喜歡使用第二種跟queryout選項(xiàng)一起使用的寫法,因?yàn)檫@樣可以更加靈活控制要導(dǎo)出的數(shù)據(jù)。如果執(zhí)行BCP命令遇到這樣的錯(cuò)誤提示:

Msg 15281, Level 16, State 1, Procedure xp_cmdshell, Line 1
SQL Server blocked access to procedure 'sys.xp_cmdshell' of component 'xp_cmdshell' because this component is turned off as part of the security configuration for this server. A system administrator can enable the use of 'xp_cmdshell' by using sp_configure. For more information about enabling 'xp_cmdshell', see "Surface Area Configuration" in SQL Server Books Online.


系統(tǒng)默認(rèn)沒(méi)有開(kāi)啟xp_cmdshell選項(xiàng)。使用下面語(yǔ)句開(kāi)啟此選項(xiàng)。

EXEC?sp_configure?'show?advanced?options',?1 RECONFIGURE GO EXEC?sp_configure?'xp_cmdshell',?1 RECONFIGURE GO

code-3

?

使用完之后,可以把sp_cmdshell關(guān)閉。

EXEC?sp_configure?'show?advanced?options',?1 RECONFIGURE GO EXEC?sp_configure?'xp_cmdshell',?0 RECONFIGURE GO


code-4


BCP導(dǎo)入數(shù)據(jù)

修改figure-2中的out為in即可,把數(shù)據(jù)導(dǎo)入。

figure-6

?

figure-7

?

使用BULK INSERT導(dǎo)入數(shù)據(jù)

BULK?INSERT?dbo.T1?FROM?'E:\T1.txt'WITH?(FIELDTERMINATOR?=?'\t',ROWTERMINATOR?=?'\n'????)

code-5

?

figure-8

?

關(guān)于BULK INSERT更詳細(xì)的說(shuō)明,參考:https://msdn.microsoft.com/zh-cn/library/ms188365%28v=sql.105%29.aspx

相比BCP的導(dǎo)入,BULK INSERT提供更靈活的選擇。

?

BCP幾個(gè)常用的參數(shù)說(shuō)明:

database_name指定的表或視圖所在數(shù)據(jù)庫(kù)的名稱。如果未指定,則使用用戶的默認(rèn)數(shù)據(jù)庫(kù)。
in | out| queryout | format
  • in 從文件復(fù)制到數(shù)據(jù)庫(kù)表或視圖。

  • out 從數(shù)據(jù)庫(kù)表或視圖復(fù)制到文件。如果指定了現(xiàn)有文件,則該文件將被覆蓋。提取數(shù)據(jù)時(shí),請(qǐng)注意 bcp 實(shí)用工具將空字符串表示為 null,而將 null 字符串表示為空字符串。

  • queryout 從查詢中復(fù)制,僅當(dāng)從查詢大容量復(fù)制數(shù)據(jù)時(shí)才必須指定此選項(xiàng)。

  • format 根據(jù)指定的選項(xiàng)(-n-c-w-N)以及表或視圖的分隔符創(chuàng)建格式化文件。大容量復(fù)制數(shù)據(jù)時(shí),bcp 命令可以引用一個(gè)格式化文件,從而避免以交互方式重復(fù)輸入格式信息。format 選項(xiàng)要求指定 -f 選項(xiàng);創(chuàng)建 XML 格式化文件時(shí)還需要指定 -x 選項(xiàng)。

    in 從文件復(fù)制到數(shù)據(jù)庫(kù)表或視圖。
    out 從數(shù)據(jù)庫(kù)表或視圖復(fù)制到文件。如果指定了現(xiàn)有文件,則該文件將被覆蓋。提取數(shù)據(jù)時(shí),請(qǐng)注意 bcp 實(shí)用工具將空字符串表示為 null,而將 null 字符串表示為空字符串。
    queryout 從查詢中復(fù)制,僅當(dāng)從查詢大容量復(fù)制數(shù)據(jù)時(shí)才必須指定此選項(xiàng)。

-c使用字符數(shù)據(jù)類型執(zhí)行該操作。此選項(xiàng)不提示輸入每個(gè)字段;它使用 char 作為存儲(chǔ)類型,不帶前綴;使用 \t(制表符)作為字段分隔符,使用 \r\n(換行符)作為行終止符。
-w使用 Unicode 字符執(zhí)行大容量復(fù)制操作。此選項(xiàng)不提示輸入每個(gè)字段;它使用 nchar 作為存儲(chǔ)類型,不帶前綴;使用 \t(制表符)作為字段分隔符,使用 \n(換行符)作為行終止符。
-tfield_term指定字段終止符。默認(rèn)值為 \t(制表符)。使用此參數(shù)可以替代默認(rèn)字段終止符。
-rrow_term指定行終止符。默認(rèn)值為 \n(換行符)。使用此參數(shù)可替代默認(rèn)行終止符。
-Sserver_name[ \instance_name]指定要連接的 SQL Server 實(shí)例。如果未指定服務(wù)器,則 bcp 實(shí)用工具將連接到本地計(jì)算機(jī)上的默認(rèn) SQL Server 實(shí)例。如果從網(wǎng)絡(luò)或本地命名實(shí)例上的遠(yuǎn)程計(jì)算機(jī)中運(yùn)行 bcp 命令,則必須使用此選項(xiàng)。若要連接到服務(wù)器上的 SQL Server 默認(rèn)實(shí)例,請(qǐng)僅指定 server_name。若要連接到 SQL Server 的命名實(shí)例,請(qǐng)指定 server_name\instance_name。
-Ulogin_id指定用于連接到 SQL Server 的登錄 ID。
-Ppassword指定登錄 ID 的密碼。如果未使用此選項(xiàng),bcp 命令將提示輸入密碼。如果在命令提示符的末尾使用此選項(xiàng),但不提供密碼,則 bcp 將使用默認(rèn)密碼 (NULL)。
-T指定 bcp 實(shí)用工具通過(guò)使用集成安全性的可信連接連接到 SQL Server。不需要網(wǎng)絡(luò)用戶的安全憑據(jù)、login_id 和 password。如果未指定 –T,則需要指定 –U–P 才能成功登錄。

更詳細(xì)的參數(shù),請(qǐng)參考:https://msdn.microsoft.com/zh-cn/library/ms162802%28v=sql.105%29.aspx




2. 實(shí)踐

2.1 導(dǎo)出數(shù)據(jù)

介紹完BCP的導(dǎo)出導(dǎo)入,以及BULK INSERT的導(dǎo)入,下面進(jìn)行一些實(shí)際的操作。為了接近實(shí)際環(huán)境,創(chuàng)建一張10個(gè)字段的表,包含有幾種常用的數(shù)據(jù)類型,構(gòu)造2000萬(wàn)的數(shù)據(jù),包含中文和 英文。為了更快插入測(cè)試數(shù)據(jù),先不創(chuàng)建索引。在執(zhí)行下面代碼之前,請(qǐng)留意下數(shù)據(jù)庫(kù)的日志恢復(fù)模式是否設(shè)置為大容量模式或簡(jiǎn)單模式,以及磁盤空間是否足夠 (我的實(shí)踐中,數(shù)據(jù)生成后數(shù)據(jù)文件和日志文件大概需要40G的空間)。


USE?AdventureWorks2008R2 GO IF?OBJECT_ID(N'T1')?IS?NOT?NULL BEGINDROP?TABLE?T1 END GOCREATE?TABLE?T1?(id_?INT,col_1?NVARCHAR(50),col_2?NVARCHAR(40),col_3?NVARCHAR(40),col_4?NVARCHAR(40),col_5?INT,col_6?FLOAT,col_7?DECIMAL(18,8),col_8?BIT ) GOWITH?CTE1?AS?(? SELECT? ROW_NUMBER()?OVER?(ORDER?BY?a.[object_id]?ASC)?as?row_no, a.[object_id]? FROM?master.sys.all_objects?AS?aCROSS?JOIN?master.sys.all_objects?AS?bCROSS?JOIN?sys.databases?AS?c WHERE?c.database_id?<=?5 )INSERT?INTO?T1?(id_,col_1,col_2,col_3,col_4,col_5,col_6,col_7,col_8) SELECT? row_no, REPLICATE(N'廣州市?',10), NEWID(), NEWID(), NEWID(), CAST(row_no?*?RAND()?*?10?AS?INT), row_no?*?RAND(), row_no?*?RAND(), CAST(row_no?*?RAND()?AS?INT)?%?2 FROM?CTE1? WHERE?row_no?<=?20GO

code-6

?

過(guò)程要花上幾分鐘的時(shí)間才能完成,請(qǐng)耐心等待一下。關(guān)于數(shù)據(jù)的構(gòu)造,可以參考我的另一篇博文:http://fishparadise.blog.51cto.com/11284420/1750798

使用上面介紹的用法導(dǎo)出數(shù)據(jù):

EXEC?[master]..xp_cmdshell' BCP?AdventureWorks2008R2.dbo.T1?out?E:\T1_04.txt?-w?-T?-S?KEN\SQLSERVER08R2' GO

code-7


這里使用-w參數(shù)。BCP可以在CMD下導(dǎo)出數(shù)據(jù),測(cè)試導(dǎo)出2000萬(wàn)條記錄,我的筆記本使用了近8分鐘左右的時(shí)間。BCP同時(shí)也可以在SSMS中執(zhí)行,使用了6分多鐘時(shí)間,比CMD下速度要快些,生成的文件大小一致,每個(gè)文件近5GB。

figure-9

?

figure-10

?

而對(duì)于復(fù)雜的大容量導(dǎo)入情況,通常都會(huì)需要格式化文件。在以下情況下,必須使用格式化文件:

  • 具有不同架構(gòu)的多個(gè)表使用同一數(shù)據(jù)文件作為數(shù)據(jù)源。

  • 數(shù)據(jù)文件中的字段數(shù)不同于目標(biāo)表中的列數(shù);例如:

    ?

    • 目標(biāo)表中至少包含一個(gè)定義了默認(rèn)值或允許為 NULL 的列。

    • 用戶不具有對(duì)目標(biāo)表的一個(gè)或多個(gè)列的 SELECT/INSERT 權(quán)限。

    • 具有不同架構(gòu)的兩個(gè)或多個(gè)表使用同一個(gè)數(shù)據(jù)文件。

  • 數(shù)據(jù)文件和表的列順序不同。

  • 數(shù)據(jù)文件列的終止字符或前綴長(zhǎng)度不同。

?

這里不使用格式化文件進(jìn)行導(dǎo)出導(dǎo)入的演示了。詳細(xì)介紹與使用,請(qǐng)參考聯(lián)機(jī)叢書。



2.2 導(dǎo)入數(shù)據(jù)

使用BULK INSERT把數(shù)據(jù)導(dǎo)入到目標(biāo)表數(shù)據(jù)。為提高性能,可臨時(shí)刪除索引,導(dǎo)完之后再重建索引等。請(qǐng)注意要預(yù)留足夠的磁盤空間。這里大概花了15分鐘導(dǎo)完。

figure-11

?



3. 擴(kuò)展

3.1 數(shù)據(jù)導(dǎo)出導(dǎo)入自動(dòng)化與數(shù)據(jù)接口

由于工作關(guān)系,有時(shí)要開(kāi)發(fā)一些客戶的數(shù)據(jù)接口,每天自動(dòng)導(dǎo)入比較大量的數(shù)據(jù)。限制于應(yīng)用程序等因素影響,所以考慮直接使用SQL SERVER的BULK INSERT每天自動(dòng)去讀取相關(guān)目錄的中間文件。盡管目錄是動(dòng)態(tài)的,但由于中間文件是固定格式的,通過(guò)編寫動(dòng)態(tài)SQL,最后封裝成存儲(chǔ)過(guò)程,放到JOB 中,配置運(yùn)行的計(jì)劃,即可完成自動(dòng)化的工作。下面簡(jiǎn)單演示下過(guò)程:

?

3.1.1 編寫導(dǎo)入腳本

CREATE?PROCEDURE?sp_import_data AS BEGIN? DECLARE?@path?NVARCHAR(500) DECLARE?@sql?NVARCHAR(MAX)/*S_PARAMETERS表是可以在應(yīng)用程序上配置路徑的*/ SELECT??@path?=?value_?+?CONVERT(NVARCHAR,?getdate(),?23)?+?'.txt'? FROM?S_PARAMETERS?WHERE?[type]?=?'Import'/*T4是一張臨時(shí)的中間表。先把數(shù)據(jù)從文件中讀入到中間表, 最后通過(guò)腳本把T4中間表的數(shù)據(jù)插入到實(shí)際的業(yè)務(wù)表中*/ SET?@sql=N'BULK?INSERT?T4?FROM?'''+?@path?+?''' WITH?(FIELDTERMINATOR?=?''*'',ROWTERMINATOR?=?''\n'')' EXEC?(@sql) END GO

code-8

?

3.1.2 配置JOB

首先要配置好的是SQL SERVER有權(quán)限讀取相關(guān)目錄和文件的權(quán)限。在Sql Server Configuration Manager --> SQL Server Services 選擇相應(yīng)的實(shí)例,右鍵選擇屬性,在Log On頁(yè)簽,使用有足夠權(quán)限啟動(dòng)SQL SERVER和有權(quán)限讀取相關(guān)目錄的用戶,比如讀取網(wǎng)絡(luò)盤。

figure-12

?

在SQL Server Agent新建一個(gè)作業(yè)

figure-13

?

在General頁(yè),選擇Owner,這里選擇sa。

figure-14

?

在Steps頁(yè),在Command里執(zhí)行寫好的存儲(chǔ)過(guò)程。

figure-15

?

在Schedules頁(yè),配置執(zhí)行的時(shí)間和頻率等。完成。

figure-16



3.2 高版本數(shù)據(jù)庫(kù)降級(jí)到低版本

一般來(lái)說(shuō),從低版本備份的數(shù)據(jù)庫(kù)可以直接在高版本的數(shù)據(jù)庫(kù)中恢復(fù)的,比如SQL2000的備份可以在SQL2005或SQL2008中恢復(fù),除非是 跨度太大的之外。比如SQL2000的備份就不能直接在SQL2012中恢復(fù),只能恢復(fù)到SQL2008,再?gòu)腟QL2008備份出來(lái),最后到 SQL2012上恢復(fù)。

而高版本的備份一般不能在低版本中恢復(fù),如SQL2008的備份不能在SQL2005或SQL2000中恢復(fù)。而實(shí)際中,卻又會(huì)遇到這種需求。最好 是通過(guò)高版本SSMS直接連接兩個(gè)不同版本的數(shù)據(jù)庫(kù),通過(guò)數(shù)據(jù)庫(kù)間的數(shù)據(jù)導(dǎo)出導(dǎo)入或?qū)懩_本,把高版本的數(shù)據(jù)導(dǎo)到低版本的數(shù)據(jù)庫(kù)中。這是比較快速安全的方 法。但是如果兩個(gè)版本的數(shù)據(jù)庫(kù)不能相連,只能是把數(shù)據(jù)導(dǎo)出來(lái),再導(dǎo)入。對(duì)于數(shù)據(jù)量不大來(lái)說(shuō),使用SSMS的導(dǎo)出導(dǎo)入功能,或是生成包含數(shù)據(jù)的腳本即可(下 圖)。對(duì)于大數(shù)據(jù)來(lái)說(shuō),卻是一個(gè)災(zāi)難,如前面有2000萬(wàn)數(shù)據(jù)的大表,生成數(shù)據(jù)的腳本也有幾個(gè)G大,直接使用SSMS執(zhí)行是不可能的了。只能是使用 SQLCMD實(shí)用工具,在后臺(tái)執(zhí)行SQL腳本,或者借助BCP、BULK INSERT等這種大容量數(shù)據(jù)導(dǎo)出導(dǎo)入的工具。

figure-17

?

4. 總結(jié)

使用BCP并結(jié)合BULK INSERT可實(shí)現(xiàn)大容量數(shù)據(jù)的快速導(dǎo)出導(dǎo)入,并可以實(shí)現(xiàn)其自動(dòng)化工作。對(duì)于少量數(shù)據(jù)來(lái)說(shuō),操作也不算很復(fù)雜。這是除了SSMS上的圖形化工具之外,又一個(gè)非常實(shí)用的工具。


轉(zhuǎn)載于:https://blog.51cto.com/fishparadise/1750787

總結(jié)

以上是生活随笔為你收集整理的BCP导出导入大容量数据实践的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。