2017-02-13 4 views
0

У меня есть таблица с именем REFERENCES, которая содержит несколько сотен тысяч строк XML, которые я хотел бы извлечь как отдельные файлы XML.Экспорт строк столбца XML из таблицы SQL в отдельные файлы

Это примерно отформатирован как таковую:

+--------------+------------------+ 
| 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() и прочитайте ReferenceID в @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

Смежные вопросы