[英]Inserting XML documents into SQL Server 2008 database
我需要将xml文件插入SQL Server 2008的帮助。
我有以下SQL语句:
insert into dbo.articles(id, title, contents)
SELECT X.article.query('id').value('.', 'INT'),
X.article.query('article').value('.', 'VARCHAR(50)'),
X.article.query('/doc/text()').value('.', 'VARCHAR(MAX)')
FROM (
SELECT CAST(x AS XML)
FROM OPENROWSET(
BULK 'E:\test\test_files\1000006.xml',
SINGLE_BLOB) AS T(x)
) AS T(x)
CROSS APPLY x.nodes('doc') AS X(article);
基本上将XML文档切成一列。 但是,我希望能够将所有文件插入文件夹中,而不是手动指定文件,在这种情况下为E:\\ test \\ test_files \\ 1000006.xml
好的,首先要回答stackoverflow中的一个问题...
您有两个问题:-首先将文件夹中的文件名放入SQL表或表变量中,然后从每个文件中读取XML。
第一个很简单,如果您不介意使用xp_cmdshell
DECLARE @Folder VARCHAR(255) = 'C:\temp\*.xml'
DECLARE @Command VARCHAR(255)
DECLARE @FilesInAFolder TABLE (XMLFileName VARCHAR(500))
--
SET @Command = 'DIR ' + @Folder + ' /TC /b'
--
INSERT INTO @FilesInAFolder
EXEC MASTER..xp_cmdshell @Command
--
SELECT * FROM @FilesInAFolder
WHERE XMLFileName IS NOT NULL
第二部分,将XML文件转换为SQL行有点棘手,因为BULK INSERT不会接受参数,并且您不能将BULK INSERT转换为XML表类型。 这是适用于一个文件的代码...
DECLARE @x xml
DECLARE @Results TABLE (result xml)
DECLARE @xmlFileName NVARCHAR(300) = 'C:\temp\YourXMLFile.xml'
DECLARE @TempTable TABLE
(
ID INT,
Article NVARCHAR(50),
doctext NVARCHAR(MAX)
)
/* ---- HAVE TO USE DYNAMIC sql BECAUSE BULK INSERT WON'T TAKE A PARAMETER---------*/
DECLARE @sql NVARCHAR(4000) =
'SELECT * FROM OPENROWSET ( BULK ''' + @xmlFileName + ''', SINGLE_BLOB )AS xmlData'
/* ---- have to use a normal table variable because we can't directly bulk insert
into an XML type table variable ------------------------------------------*/
INSERT INTO @results EXEC(@SQL)
SELECT @x = result FROM @Results
/* ---- this is MUCH faster than using a cross-apply ------------------------------*/
INSERT INTO @TempTable(ID,Article,doctext)
SELECT
x.value('ID[1]', 'INT' ),
x.value('Article[1]', 'NVARCHAR(50)' ),
x.value('doctext[1]', 'NVARCHAR(MAX)' )
FROM @x.nodes(N'/doc') t(x)
SELECT * FROM @TempTable
现在,很难将这两者放在一起。 我尝试了几种方法将此代码放入函数中,但是您不能在函数中使用动态SQL或EXEC,也不能从函数中调用SP,也不能将代码放入两个单独的SP中,因为您可以没有级联的EXEC语句,即您尝试使用上面的代码在其中执行EXEC的SP中也包含EXEC,因此...您必须使用光标将上面的两个代码块放在一起,即光标通过@FilesInAFolder将每个XMLFileName值作为变量@XMLFileName传递到第二个代码块中,或者您使用SSIS或CLR。
抱歉,我没有时间用目录名作为参数和游标来构建一个完整的SP,但这很简单。 !
您正在使用存储过程吗? 您可以将文件名指定为参数。
就像是...
CREATE PROCEDURE sp_XMLLoad
@FileName
AS SET NOCOUNT ON
SELECT X.article.query('id').value('.', 'INT'),
X.article.query('article').value('.', 'VARCHAR(50)'),
X.article.query('/doc/text()').value('.', 'VARCHAR(MAX)')
FROM (
SELECT CAST(x AS XML)
FROM OPENROWSET(
BULK @FileName,
SINGLE_BLOB) AS T(x)
不完全一样...您需要在我打赌的@Filename周围加上引号。 也许用引号将其组合起来,然后使用该变量。
如果使用的是SSIS,则可以将目录中的所有文件泵送到存储过程或所用的SSIS代码中。
我认为您可以使用游标和xp_cmdshell做到这一点。 我不建议您使用xp_cmdshell。
DECLARE @FilesInAFolder TABLE (FileNames VARCHAR(500))
DECLARE @File VARCHAR(500)
INSERT INTO @FilesInAFolder
EXEC MASTER..xp_cmdshell 'dir /b c:\'
DECLARE CU CURSOR FOR
SELECT 'c:\' + FileNames
FROM @FilesInAFolder
WHERE RIGHT(FileNames,4) = '.xml'
OPEN CU
FETCH NEXT FROM CU INTO @File
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO dbo.articles(id, title, contents)
SELECT X.article.query('id').value('.', 'INT'),
X.article.query('article').value('.', 'VARCHAR(50)'),
X.article.query('/doc/text()').value('.', 'VARCHAR(MAX)')
FROM (
SELECT CAST(x AS XML)
FROM OPENROWSET(
BULK @File,
SINGLE_BLOB) AS T(x)
) AS T(x)
CROSS APPLY x.nodes('doc') AS X(article);
FETCH NEXT FROM CU INTO @File
END
CLOSE CU
DEALLOCATE CU
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.