2017-02-13 3 views
0

REFERENCESというテーブルがあります。このテーブルには、数十万行のXML行が含まれており、個別のXMLファイルとして抽出します。SQLテーブルから個々のファイルにXML列の行をエクスポートする

は、それはおおよそようにフォーマットされる:私はすべての行およびバルクエクスポートREFERENCE_IDとして各REFERENCE_XML列と名称を介してループしたい

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

マイ出力フォルダのセットは、次のようなになります。

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

私は単一の静的行に対する操作を行い、ラフなクエリを見つけることができたが、私は最善の方法を考え出す困難な時間を過ごしていますWHILEループまたはCURSORを作成します。 REFERENCESテーブル内のすべての行をループし、すべてのXMLを個別のファイルとしてエクスポートするには、ファイル名とWHERE句を動的にするにはどうすればよいですか?

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

。これは、すべての反復で完全な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; 

これは、プリントアウトである:REFERENCE_IDは= '+ id`キャストせずに動作しません@' WHERE

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

私はこのような何かをしたい:あなたはCURSORを開始する上で直接実行されている番号を作成するためにROW_NUMBER()を使用することができます

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

この '... id' @原因は' 'として宣言されていますINT' – Shnugo

関連する問題