2017-02-13 2 views
0

Ich habe eine Tabelle namens REFERENCES, die ein paar hunderttausend Zeilen von XML enthält, die ich als einzelne XML-Dateien extrahieren möchte.XML-Spaltenzeilen von SQL-Tabelle in einzelne Dateien exportieren

Es ist grob als solche formatiert:

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

ich es als REFERENCE_ID jede Zeile durchlaufen und Massenexport jede REFERENCE_XML Spalte und den Namen möchte.

Mein Ausgabeordner Satz würde als solche aussehen:

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

konnte ich eine grobe Abfrage finden, die den Betrieb für eine einzelne statische Zeile durchführt, aber ich bin eine schwierige Zeit, die die beste Art und Weise, herauszufinden, um eine WHILE Schleife oder CURSOR zu erstellen. Wie mache ich den Dateinamen und WHERE Klausel dynamisch, um durch jede Zeile in der REFERENCES Tabelle durchlaufen und exportieren Sie alle XMLs als einzelne Dateien?

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 

Antwort

2

Sie ROW_NUMBER() können eine laufende Nummer direkt ein CURSOR beim Start zu erstellen. Dies scheint einfacher als eine vollständige SELECT bei jeder Iteration aufzurufen.

Bearbeiten: Ich war zu schnell. Sie möchten Ihre als Nummer verwenden. Gehen Sie einfach so ohne ROW_NUMBER() und lesen Sie die ReferenceID in @Nr bei jeder Iteration.

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; 

Dies ist der Ausdruck:

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

Mit ein paar Modifikationen (vor allem an der @sqlStr-Linie) konnte ich erfolgreich arbeiten. Ich fand es nicht notwendig, das XML als NVARCHAR zu interpretieren. bcp konnte das XML ohne Probleme verarbeiten. Vielen Dank! – PicoDeGallo

0

Ich würde so etwas tun:

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

Diese '... WHERE REFERENCE_ID = '+ @ id' ohne Guss wird nicht funktionieren, weil' @ id' als deklariert ist ' INT' – Shnugo

Verwandte Themen