1. 程式人生 > >SQL Server大容量匯入和匯出 XML 文件的示例

SQL Server大容量匯入和匯出 XML 文件的示例

本主題適用於: yesSQL Server(從 2016 開始)noAzure SQL 資料庫noAzure SQL 資料倉庫no並行資料倉庫

可以將 XML 文件大容量匯入到 SQL Server 資料庫中,也可以從 SQL Server 資料庫中大容量匯出 XML 文件。 本主題提供了這兩種情況的示例。

若要將資料從一個數據檔案大容量匯入 SQL Server 表或未分割槽檢視,可以使用以下工具或命令:

  • bcp 實用工具
    還可以使用 bcp 實用工具將資料從可執行 SELECT 語句的 SQL Server 資料庫的任意位置(包括分割槽檢視)匯出。

  • BULK INSERT

  • INSERT ... SELECT * FROM OPENROWSET(BULK...)

示例

下列示例說明了以下操作內容:

在從檔案大容量匯入 XML 資料時,如果檔案中包含您要應用的編碼宣告,則應在 OPENROWSET(BULK…) 子句中指定 SINGLE_BLOB 選項。 SINGLE_BLOB 選項可確保 SQL Server 中的 XML 分析器根據 XML 宣告中指定的編碼方案匯入資料。

示例表

若要測試下方的示例 A,請建立示例表 T

USE tempdb  
CREATE TABLE T (IntCol int, XmlCol xml);  
GO  

示例資料檔案

在執行示例 A 之前,必須先建立一個 UTF-8 編碼檔案 (C:\SampleFolder\SampleData3.txt

),該檔案應包含指定 UTF-8 編碼方案的以下示例例項。

<?xml version="1.0" encoding="UTF-8"?>  
<Root>  
          <ProductDescription ProductModelID="5">  
             <Summary>Some Text</Summary>  
          </ProductDescription>  
</Root>  

示例 A

此示例使用 SINGLE_BLOB 語句中的 INSERT ... SELECT * FROM OPENROWSET(BULK...)

 選項從名為 SampleData3.txt 的檔案中匯入資料,並在包含單列的示例表 T 中插入一個 XML 例項。

INSERT INTO T(XmlCol)  
SELECT * FROM OPENROWSET(  
   BULK 'c:\SampleFolder\SampleData3.txt',  
   SINGLE_BLOB) AS x;  

註釋

在這個例子中,通過使用 SINGLE_BLOB,可以避免 XML 文件的編碼(由 XML 編碼宣告所指定)與伺服器隱含使用的字串內碼表不匹配的問題。

如果使用 NCLOB 或 CLOB 資料型別且遇到內碼表或編碼衝突,則必須執行下列操作之一:

  • 刪除 XML 宣告,以成功匯入 XML 資料檔案的內容。

  • 在查詢的 CODEPAGE 選項中指定一個內碼表,該內碼表須與 XML 宣告中使用的編碼方案相匹配。

  • 使用非 Unicode XML 編碼方案匹配或解析資料庫排序規則設定。

此示例使用 OPENROWSET 大容量行集提供程式向示例表 T 中的現有行新增一個 XML 例項。

System_CAPS_ICON_note.jpg 說明


若要執行此示例,必須先完成示例 A 中提供的測試指令碼。該示例建立了 tempdb.dbo.T 表,並從 SampleData3.txt 中大容量匯入資料。

示例資料檔案

示例 B 使用的是上例所使用 SampleData3.txt 示例資料檔案的修改版本。 若要執行此示例,請按如下所示修改此檔案的內容:

<Root>  
          <ProductDescription ProductModelID="10">  
             <Summary>Some New Text</Summary>  
          </ProductDescription>  
</Root>  

示例 B

-- Query before update shows initial state of XmlCol values.  
SELECT * FROM T  
UPDATE T  
SET XmlCol =(  
SELECT * FROM OPENROWSET(  
   BULK 'C:\SampleFolder\SampleData3.txt',  
           SINGLE_BLOB  
) AS x  
)  
WHERE IntCol = 1;  
GO  

System_CAPS_ICON_important.jpg 重要事項


若非您的 XML 環境有特殊要求,建議不要啟用對文件型別定義 (DTD) 的支援。 啟用 DTD 支援會增加伺服器的可攻擊外圍應用,並且可能會使它受到拒絕服務攻擊。 如果必須啟用 DTD 支援,可以通過僅處理可信的 XML 文件來降低安全風險。

在嘗試使用 bcp 命令從包含 DTD 的檔案中匯入 XML 資料的過程中,可能會出現如下錯誤:

“SQLState = 42000,NativeError = 6359”

“錯誤 = [Microsoft][SQL Server Native Client][SQL Server]不允許使用內部子集 DTD 分析 XML。 請將 CONVERT 與樣式選項 2 一起使用,以啟用有限的內部子集 DTD 支援。”

“BCP 複製 %s 失敗”

若要解決此問題,可以使用 OPENROWSET(BULK...) 函式,並在命令的 CONVERT 子句中指定 SELECT 選項,以從包含 DTD 的資料檔案中匯入 XML 資料。 該命令的基本語法如下:

INSERT ... SELECT CONVERT(…) FROM OPENROWSET(BULK...)

示例資料檔案

在測試此批量匯入示例之前,需要先建立一個包含以下示例例項的檔案 (C:\temp\Dtdfile.xml):

<!DOCTYPE DOC [<!ATTLIST elem1 attr1 CDATA "defVal1">]><elem1>January</elem1>  

示例表

示例 C 使用由以下 T1 語句建立的 CREATE TABLE 示例表:

USE tempdb;  
CREATE TABLE T1(XmlCol xml);  
GO  

示例 C

此示例使用 OPENROWSET(BULK...) ,並在 CONVERT 子句中指定了 SELECT 選項,從而將 XML 資料從 Dtdfile.xml 匯入到了示例表 T1中。

INSERT T1  
  SELECT CONVERT(xml, BulkColumn, 2) FROM   
    OPENROWSET(Bulk 'c:\temp\Dtdfile.xml', SINGLE_BLOB) [rowsetresults];  

執行 INSERT 語句後,會將 DTD 從 XML 中提取出來,並存儲到 T1 表中。

下面的示例說明如何大容量匯入 XML 文件 Xmltable.dat

示例資料檔案

Xmltable.dat 中的文件包含兩個 XML 值,每行一個。 第一個 XML 值的編碼為 UTF-16,第二個值的編碼為 UTF-8。

下面的十六進位制轉儲顯示了此資料檔案的內容:

FF FE 3C 00 3F 00 78 00-6D 00 6C 00 20 00 76 00  *..<.?.x.m.l. .v.*  
65 00 72 00 73 00 69 00-6F 00 6E 00 3D 00 22 00  *e.r.s.i.o.n.=.".*  
31 00 2E 00 30 00 22 00-20 00 65 00 6E 00 63 00  *1...0.". .e.n.c.*  
6F 00 64 00 69 00 6E 00-67 00 3D 00 22 00 75 00  *o.d.i.n.g.=.".u.*  
74 00 66 00 2D 00 31 00-36 00 22 00 3F 00 3E 00  *t.f.-.1.6.".?.>.*  
3C 00 72 00 6F 00 6F 00-74 00 3E 00 A2 4F 9C 76  *<.r.o.o.t.>..O.v*  
0C FA 77 E4 80 00 89 00-00 06 90 06 91 2E 9B 2E  *..w.............*  
99 34 A2 34 86 00 83 02-92 20 7F 02 4E C5 E4 A3  *.4.4..... ..N...*  
34 B2 B7 B3 B7 FE F8 FF-F8 00 3C 00 2F 00 72 00  *4.........<./.r.*  
6F 00 6F 00 74 00 3E 00-00 00 00 00 7A EF BB BF  *o.o.t.>.....z...*  
3C 3F 78 6D 6C 20 76 65-72 73 69 6F 6E 3D 22 31  *<?xml version="1*  
2E 30 22 20 65 6E 63 6F-64 69 6E 67 3D 22 75 74  *.0" encoding="ut*  
66 2D 38 22 3F 3E 3C 72-6F 6F 74 3E E4 BE A2 E7  *f-8"?><root>....*  
9A 9C EF A8 8C EE 91 B7-C2 80 C2 89 D8 80 DA 90  *................*  
E2 BA 91 E2 BA 9B E3 92-99 E3 92 A2 C2 86 CA 83  *................*  
E2 82 92 C9 BF EC 95 8E-EA 8F A4 EB 88 B4 EB 8E  *................*  
B7 EF BA B7 EF BF B8 C3-B8 3C 2F 72 6F 6F 74 3E  *.........</root>*  
00 00 00 00 7A                                   *....z*  

示例表

大容量匯入或匯出 XML 文件時,應當使用在任何文件中都不可能出現的欄位終止符;例如,在連續四個 Null (\0) 後緊跟字母 z\0\0\0\0z

此示例說明如何為 xTable 示例表使用此欄位終止符。 若要建立此示例表,請使用下列 CREATE TABLE 語句:

USE tempdb;  
CREATE TABLE xTable (xCol xml);  
GO  

示例格式化檔案

必須在格式化檔案中指定欄位終止符。 示例 D 使用了一個名為 Xmltable.fmt 的非 XML 格式化檔案,該檔案包含以下內容:

9.0  
1  
1       SQLBINARY     0       0       "\0\0\0\0z"    1     xCol         ""  

可以使用此格式化檔案並通過 xTable 命令、bcp 語句或 BULK INSERT 語句將 XML 文件大容量匯入到 INSERT ... SELECT * FROM OPENROWSET(BULK...) 表中。

示例 D

此示例在 Xmltable.fmt 語句中使用 BULK INSERT 格式化檔案來匯入 XML 資料檔案 Xmltable.dat 中的內容。

BULK INSERT xTable   
FROM 'C:\Xmltable.dat'  
WITH (FORMATFILE = 'C:\Xmltable.fmt');  
GO  

下面的示例使用 bcp 命令和同一個 XML 格式化檔案從上一示例所建立的表中大容量匯出 XML 資料。 在下面的 bcp 命令中, <server_name> 和<instance_name> 代表必須使用相應的值替換的佔位符:

bcp bulktest..xTable out a-wn.out -N -T -S<server_name>\<instance_name>  

System_CAPS_ICON_note.jpg 說明


SQL Server 不儲存 XML 編碼。 因此,在匯出 XML 資料時,XML 欄位的原始編碼將不可用。 SQL Server 匯出 XML 資料時,使用 UTF-16 編碼。

另請參閱