數據導出不只是bcp這一種方式,不過(guò)bcp的最大優(yōu)點(diǎn)是可以根據id批量導出數據,這樣是節省時(shí)間的。還有一種是直接在頁(yè)面導出數據,頁(yè)面列出數據庫中的數據,然后選擇一種方式(如xls)導出來(lái)。
由于日?;径际桥c數據庫打交道,我會(huì )經(jīng)常遇到數據轉移的需求。類(lèi)似于:將服務(wù)器A的表數據轉移到服務(wù)器B的同名表中,或將線(xiàn)上服務(wù)器的一部分數據拉到線(xiàn)下測試服務(wù)器供開(kāi)發(fā)人員調試。通常來(lái)說(shuō),有以下幾種表到表的復制方法:
1.建鏈接服務(wù)器,寫(xiě)INSERT語(yǔ)句。 適用于兩臺服務(wù)器能互相連接,在表的數量比較少的情況下,手動(dòng)寫(xiě)INSERT語(yǔ)句還是可以接受的。但如果兩臺服務(wù)器無(wú)法互聯(lián)或連接速度較慢,或者多個(gè)表需要手寫(xiě)插入列名,寫(xiě)起來(lái)會(huì )很麻煩,還要調試語(yǔ)句。
2.查詢(xún)出所有數據或需要導出的數據或用導出工具存成EXCEL,再用導入工具導入目標表。對于數據量不大、比較標準、可以規則的存成EXCEL的數據可以使用這種方法,反之會(huì )有各種問(wèn)題,最常見(jiàn)的就是大文本在導出成EXCEL后經(jīng)常會(huì )無(wú)法原樣導入,報各種格式錯。
3.查出需要導出的數據,復制一下,在SSMS的編輯兩200行中選中行復制。這種方法和第二種問(wèn)題類(lèi)似,更快一點(diǎn),但要求也更嚴。要求更小的數據量,更規則的數據。
4.原庫做備份--目標服務(wù)器還原備份--跨庫插入數據或者直接用還原的庫。這種能完全COPY多個(gè)表,但缺點(diǎn)一是麻煩,二是需要登陸到服務(wù)器上復制備份文件下來(lái),這在管理嚴密的公司里很可能是要領(lǐng)導簽字的。大家懂的,所以我也不常用這種方法。
5.BCP實(shí)用工具,也就是本文要介紹的,我現在最常用的數據遷移工具。無(wú)視大文本的不規則字符,無(wú)視大數據量,通過(guò)中間文件傳輸,不必登陸服務(wù)器本機。下面就從最簡(jiǎn)單的例子入手,介紹一下BCP的用法。
假設源表名T1,數據庫名DB1,服務(wù)器器實(shí)例為SERVER1,目標表名T2,數據庫名DB2,服務(wù)器實(shí)例為SERVER2。T1和T2的結構完全一樣。T2中主鍵與T1不重復或者直接是空表。
首先是導出語(yǔ)句:
BCP DB1.DBO.T1 out d:\T1.dat -S SERVER1 -U sa -P sa -n
在一臺能連接SERVER1的裝有SQLSERVER的機器上(比如SERVER1本機)的命令行CMD中運行這句命令,就會(huì )開(kāi)始運行導出程序,完成后,會(huì )在D盤(pán)生成一個(gè)名為T(mén)1.dat的文件。把這個(gè)文件COPY到一臺能連接SERVER2,裝有SQLSERVER的機器上,運行下面的導入語(yǔ)句:
BCP DB2.DBO.T2 in d:\t1.dat -S SERVER2 -U sa -P sa -n
這樣就可以了。
下面就對上面兩個(gè)語(yǔ)句做一下說(shuō)明。
BCP是命令,不解釋。
DB1.DBO.T1是指定庫名、架構名和表名。
out/in是確定方向,out是表導出,in是表導入。out可以改成queryout,對應的前面要改成查詢(xún)語(yǔ)句,也就是從DB1.DBO.T1改成"SELECT * FROM DB1.DBO.T1 WHERE ...."這樣的,實(shí)現指定數據導出。
d:\T1.dat是指定文件路徑。文件名和后綴名都是隨便寫(xiě)的,我只是習慣用這種寫(xiě)法,因為我會(huì )經(jīng)常做多個(gè)表的BCP導出,命名規律一點(diǎn)方便通過(guò)表名拼BCP語(yǔ)句。
-S -U -P 分別是指定實(shí)例名、用戶(hù)名和密碼,權限的話(huà)out需要select權限,in需要SELECT和INSERT權限,如果指定了幾個(gè)特殊選項,比如標識列原樣插入,還需要ALTER TABLE權限。
-n是指定格式,這里是指定了使用本機格式(-n),數據會(huì )以16進(jìn)制的形式存儲于文件中,因此不存在大文本干擾格式的問(wèn)題,只要兩個(gè)表的結構完全一樣,一定會(huì )成功的。
還有一些其它的格式,如-c,是為了給不同類(lèi)型的數據庫(如MYSQL或ORACLE)導入用的,它會(huì )導出成標準的文本格式,但這就會(huì )導致一些含亂碼和不規則字符的大文本干擾導入,所以我在不關(guān)注數據文件內容的時(shí)候都是用-n的格式的。
此外還有一些擴展參數,如添加-E后開(kāi)啟標識列原樣插入,用于原樣復制含有IDENTITY列的表。-b指定批大小,-F和-L指定起始和終止行數。想了解的可以去MSDN的說(shuō)明上自己了解,我就不多復制了,只提供原文地址:
http://msdn.microsoft.com/zh-cn/library/ms162802.aspx
注意除了BCP和IN/OUT,后面的所有參數都是大小寫(xiě)敏感,-S不要寫(xiě)成-s,-n和-N的含義也不同。
---------------------------------------用分割線(xiàn),就是這么自信---------------------------------------------------
下面說(shuō)一下另一種擴展。很多時(shí)候,需要導出的表有多個(gè)甚至是全庫,這時(shí)我一般會(huì )先用系統表查出表名,或在EXCEL中寫(xiě)入需要的全部表名,然后復制一下,再在CMD中粘貼,就可以實(shí)現多表的導入導出了。下面就貼出一段庫中全表BCP導出的生成SQL,供大家參考:
SELECT 'BCP DB1.DBO.'+NAME+' OUT D:\'+NAME+'.dat -S SERVER1 -U sa -P sa -n'
,'TRUNCATE TABLE '+NAME
,'BCP DB2.DBO.'+NAME+' in D:\'+NAME+'.dat -S SERVER2 -U sa -P sa -n'
FROM SYS.TABLES
ORDER BY NAME
第一句復制到cmd中導出所有文件,復制文件到能庫目標庫的機器上,先用TRUNCATE在SSMS中運行清空SERVER2上的所有待導入表,再運行第二個(gè)BCP語(yǔ)句導入。我一直是這樣做的,在結構一致的情況下,至今沒(méi)出過(guò)問(wèn)題。
另外一種方法:使用SSMS的生成腳本功能,在選項中選擇生成數據腳本(2008和R2不一樣,一個(gè)是有個(gè)是和否,另一個(gè)是三個(gè)選項:生成、生成和數據、數據),能生成表中所有INSERT的語(yǔ)句,也可以原樣復制,對于超大的數據量,生成的腳本也是超超大的,一般來(lái)說(shuō)小于1W行的數據可以使用。