我有一个名为REFERENCES
的表,其中包含几十万行XML,我想将其作为单独的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
答案 0 :(得分: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
答案 1 :(得分: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;