2017-02-13 73 views
0

我有一個表0123',它包含幾十萬行XML,我希望將其作爲單獨的XML文件提取。將SQL表中的XML列行導出到單個文件中

大致是格式化爲這樣:

+--------------+------------------+ 
| REFERENCE_ID | REFERENCE_XML | 
+--------------+------------------+ 
| 1   | <xml>...</xml> | 
| 2   | <xml>...</xml> | 
| 3   | <xml>...</xml> | 
| 4   | <xml>...</xml> | 
| ...   | <xml>...</xml> | 
| 70000  | <xml>...</xml> | 
+--------------+------------------+ 

我想通過每一行和批量出口各REFERENCE_XML列,並將它命名爲REFERENCE_ID循環。

我的輸出文件夾設置將如下這樣:

C:\References\1.xml 
C:\References\2.xml 
C:\References\3.xml 
C:\References\4.xml 
C:\References\... 
C:\References\70000.xml 

我能找到執行單個靜態行操作粗略查詢,但我有困難的時候,找出最好的辦法創建一個WHILE循環或CURSOR。如何使文件名和WHERE子句動態循環遍歷REFERENCES表中的每一行,並將所有XML導出爲單個文件?

DECLARE @fileName VARCHAR(MAX) 
DECLARE @sqlStr VARCHAR(MAX) 
DECLARE @sqlCmd VARCHAR(MAX) 

SET @fileName = 'C:\References\1.xml' -- I need the integer value to be dynamic per row. 
SET @sqlStr = SELECT REFERENCE_XML FROM REFERENCE_DB.dbo.REFERENCES WHERE REFERENCE_ID = 1' -- I need the REFERENCE_ID to be dynamic per row. 
SET @sqlCmd = 'bcp "' + @sqlStr + '" queryout ' + @fileName + ' -w -T' 

EXEC xp_cmdshell @sqlCmd 

回答

2

您可以使用ROW_NUMBER()直接在開始CURSOR創建運行數量。這似乎比在任何迭代中調用完整的SELECT容易。

編輯:我當時快。你想用你的號碼ReferenceID。在沒有ROW_NUMBER()的情況下采用相同的方式,並在每次迭代中將參考ID讀入@Nr

Declare @YourTable table (ID int,SomeXml xml); 
Insert Into @YourTable values 
(100,'<root><test a="1"/></root>') 
,(200,'<root><test a="2"/></root>') 
,(300,'<root><test a="3"/></root>'); 

DECLARE @Nr BIGINT,@ID INT,@SomeXml XML; 
DECLARE @fileName VARCHAR(MAX) 
DECLARE @sqlStr VARCHAR(MAX) 
DECLARE @sqlCmd VARCHAR(MAX) 

DECLARE cur CURSOR FOR SELECT ROW_NUMBER() OVER(ORDER BY ID) AS Nr,ID,SomeXml FROM @YourTable ; 
OPEN cur; 

FETCH NEXT FROM cur INTO @Nr,@ID,@SomeXml; 

WHILE @@FETCH_STATUS = 0 
BEGIN 

    SET @fileName = 'C:\YourPath\' + CAST(@Nr AS VARCHAR(100)) + '.xml' ; 
    SET @sqlStr = 'SELECT ''' + CAST(@SomeXml AS NVARCHAR(MAX)) + ''''; 
    SET @sqlCmd = 'bcp "' + @sqlStr + '" queryout ' + @fileName + ' -w -T'; 

    PRINT @sqlCmd; 
    --EXEC xp_cmdshell @sqlCmd 

    FETCH NEXT FROM cur INTO @Nr,@ID,@SomeXml;  
END 

CLOSE cur; 
DEALLOCATE cur; 

這是印出來的:

bcp "SELECT '<root><test a="1"/></root>'" queryout C:\DVP\1.xml -w -T 
bcp "SELECT '<root><test a="2"/></root>'" queryout C:\DVP\2.xml -w -T 
bcp "SELECT '<root><test a="3"/></root>'" queryout C:\DVP\3.xml -w -T 
+0

通過一些修改(特別是對@sqlStr行),我能夠成功完成這項工作。我沒有發現有必要將XML作爲NVARCHAR。 bcp能夠在沒有任何問題的情況下處理XML。謝謝! – PicoDeGallo

0

我會做這樣的事情:

DECLARE @fileName VARCHAR(MAX) 
DECLARE @sqlStr VARCHAR(MAX) 
DECLARE @sqlCmd VARCHAR(MAX) 
DECLARE @id int 
DECLARE myCursor CURSOR FOR 
    SELECT REFERENCE_ID FROM REFERENCE_DB.dbo.REFERENCES 
OPEN myCursor 
FETCH NEXT FROM myCursor 
INTO @id 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    SET @fileName = 'C:\References\' + @id + '.xml' 
    SET @sqlStr = SELECT REFERENCE_XML FROM REFERENCE_DB.dbo.REFERENCES WHERE REFERENCE_ID = ' + @id 
    SET @sqlCmd = 'bcp "' + @sqlStr + '" queryout ' + @fileName + ' -w -T' 

    EXEC xp_cmdshell @sqlCmd 
END 
CLOSE myCursor; 
DEALLOCATE myCursor; 
+0

這'... WHERE REFERENCE_ID = '+ @ id'不會不打石膏,工作' 事業'@ id'被聲明爲' INT' – Shnugo

相關問題