将XML文档插入SQL Server 2008数据库

将XML文档插入SQL Server 2008数据库,sql,sql-server,xml,Sql,Sql Server,Xml,我需要帮助将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('.', '

我需要帮助将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\u files\1000006.xml

是否使用存储过程?可以将文件名指定为参数

类似于

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\u cmdshell来完成此操作。不过,我不建议使用xp\u 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

好的,首先在stackoverflow中回答一个问题

您有两个问题:-首先将文件夹中的文件名获取到SQL表或表变量中,然后从每个文件夹中读取XML

第一个很简单,如果您不介意使用xp\u 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行有点棘手,因为大容量插入不会接受参数,并且不能大容量插入到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语句,也就是说,您尝试并执行一个SP,其中包含上述代码,而该SP中也包含EXEC,因此。。。您必须使用光标将上面的两个代码块放在一起,即光标穿过@FilesInAFolder,将每个XMLFileName值作为变量@XMLFileName传递到第二个代码块中,或者使用SSIS或CLR


很抱歉,我没有时间构建一个完整的SP,其中包含一个目录名作为参数和一个游标,但这非常简单。呸

那么这个过程从哪里获取文件呢?我正在尝试使用SQL Server执行代码,而不是从java或其他东西。看起来RealUlysee建议获取文件名,但我建议使用SSI和Foreach循环容器。从那里,您可以指定文件夹,并将其用作存储过程的输入(或者让SQL代码只存在于SSI中)