在 SQL Server 中,是否還有其他數據導入和導出選項
我從 SQL Server 7 開始就一直在使用 SQL Server。所以我知道 BCP、批量插入、openrowset 和 SSIS。
我的問題很簡單:
- 您是否知道使用 SQL Server Express 版本 SQL 2005 到 2014(以及即將推出的 2016)導入/導出數據的任何其他方法。
我想確保沒有其他任何東西,因為使用 BCP(這是我現在正在使用的)需要使用,
xp_cmdshell
並且出於安全原因,需要一個xp_cmdshell_proxy
帳戶。我在工作中遇到了挑戰,我想確保沒有其他東西存在,或者在我回復之前這是 Microsoft SQL Server (Express) 中的新內容。
SQLCMD 可用於導出數據。預設輸出有時難以處理,但您可以使用一些命令行選項來關閉標題、修剪尾隨空格以及使用逗號分隔符而不是預設空格:
sqlcmd -Q "SET NOCOUNT ON; SELECT TOP(10) name, object_id, type FROM sys.objects;" ^ -h-1 -W -s ","
回報:
sysrscols,3,S sysrowsets,5,S sysclones,6,S sysallocunits,7,S sysfiles1,8,S sysseobjvalues,9,S syspriorities,17,S sysdbfrag,18,S sysfgfrag,19,S sysdbfiles,20,S
使用該
-o
選項將輸出發送到文件:sqlcmd -Q "SET NOCOUNT ON; SELECT TOP(10) name, object_id, type FROM sys.objects;" ^ -h-1 -W -s "," -o C:\temp\SysObjects.txt
可以創建自定義 .NET 程序(控制台應用程序、Windows 應用程序,甚至 Web 應用程序)來導入和/或導出。對於導入,由於此處不提供表值參數 (TVP),因此有時將數據轉換/序列化為 XML 會更快,然後執行將接受 XML 參數並使用該
.nodes()
函式的儲存過程,將其反序列化到可以通過INSERT INTO table (fields) SELECT x.value(),... FROM @XmlParam.nodes();
構造插入的行中。當然,您不希望以這種方式處理 100 萬行,因此您會將導入文件分成 X 行的批次並一次發送 100 - 500 行。如果有很多數據,那麼直接語句可能會更好,但在這種情況下,您可能希望使用SqlTransactionINSERT
將每批 X 行包裝到顯式事務中。根據您(或與您一起工作的人)對 .NET 程式的熟悉程度,您可以使用 SQLCLR 建構您自己的自定義導入和/或導出功能。這適用於從 SQL Server 2005 開始的所有版本的所有 SQL Server 版本。
沿著這些構想,有一個商業可用的 SQLCLR 函式和過程庫,稱為SQL#(我是它的創建者)。一些函式和儲存過程處理數據的導入和導出。File_SplitIntoFields儲存過程返回一個結果集,其中每一行是輸入文件中的一行,但文件中的每個欄位是一個單獨的列**。**預設情況下,每個欄位的數據類型是
NVARCHAR(MAX)
,但是有一個可選的輸入參數來指定每列的確切數據類型應該是什麼。這使得它很容易做到:INSERT INTO dbo.MyImportTable (Col1, Col2, Col3, Col4) EXEC SQL#.File_SplitIntoFields @FilePath = N'', @RegExDelimiter = N',', @DataTypes = N'NVARCHAR(100),INT,DATETIME,BIT';
還有一個等效的儲存過程,稱為INET_SplitIntoFields,它做同樣的事情,但不是從文件中獲取數據,而是直接從 URL 流式傳輸數據(因此無需先在本地下載文件)。
對於導出,有一個名為DB_BulkExport的儲存過程,它結合了 SQLCMD 和 SSIS 的許多功能。我在需要進行多次導出並且無法在 SQLCMD 和 SSIS 之間做出決定之後創建了它,因為每個都有其優點和缺點,並且每個都有一個或兩個另一個沒有的功能,但所有這些功能都是需要。例如,DB_BulkExport不需要任何硬編碼的輸出欄位規範,並且可以處理
SELECT *
查詢(我不知道如何在 SSIS 中管理,但使用 SQLCMD 很容易)。它還可以處理欄位的文本限定,而無需更新源查詢以連接其中的雙引號(這使得查詢非常難看且難以維護)。事實上,它可以設置為文本限定所有欄位,或者只是根據其數據類型(字元串、日期、GUID 等)需要它的欄位。