2

今天我有一个新情况,其中客户问以下问题:

我们在一个文件夹中有 XML 文件。我们需要将这些文件加载​​到 SQL Server 表列(具有 XML 数据类型)中;我们没有将 XML 输出加载到各种 SQL Server 表中,而是将 XML 文件本身加载到 SQL Server 数据库中具有 XML 数据类型的列中。

根据客户的要求,这应该只在SSIS中完成。所以我以这种方式使用执行 SQL 任务。(除了 XML 文件,我们还需要ImportDate,FileName等)

连接类型为 OLE DB;我的 SQL 语句如下:

INSERT INTO dbo.tablename (IncomingXMLfile, ImportDate)
-- I am using just 2 columns as an example for this table--
SELECT  CONVERT(XML, BulkColumn) AS BulkColumn, GETDATE() 
FROM OPENROWSET(BULK 'C:\Mic\...........\API_Schemas\ABC.xml', SINGLE_BLOB) AS x;

当我只用一个文件进行硬编码时,这很好用。现在,在C:\Mic\...\API_Schemas文件夹中,有许多 XML 文件,我需要加载它们中的每一个,除此之外,获取它们ImportDate(即GETDATE()),以及文件本身的名称(我暂时没有在插入语句)。我必须使用 ForEachLoop 容器,并将执行 SQL 任务放在这个容器中。

所以这个问题有2个方面:

  1. 在执行 SQL 任务中参数化文件名。

  2. 使用 ForEachLoop Container(并将此 Execute SQL Task 放入其中)运行文件夹中的每个 XML 文件。

我使用了一个名为Filename(字符串数据类型)的用户变量,它的值ABC.xml是(文件夹中一系列 XML 文件中的第一个文件);我以这种方式参数化上述 TSQL 查询(见下文):

INSERT INTO dbo.tablename (IncomingXMLfile, ImportDate)
SELECT  CONVERT(XML, BulkColumn) AS BulkColumn, GETDATE() 
FROM OPENROWSET(BULK 'C:\Mic\...........\API_Schemas\?', SINGLE_BLOB) AS x;

我将此参数 ( ) 映射到此?执行 SQL 任务 (ParameterMapping选项卡) 中的用户变量文件名。查询在执行 SQL 任务中正确解析!但是,当我执行此 SQL 任务时,我收到此错误:

“参数名称无法识别。”。可能的失败原因:查询有问题,“ResultSet”属性设置不正确,参数设置不正确,或连接未正确建立。

当我将 XML 文件中的数据(使用 XML 源编辑器,使用数据访问模式(来自变量的 XML 数据)等)加载到 SQL Server 表中时,这种情况完全不同。在我们的例子中,我们将 XML 文件本身加载到具有 XML 数据类型的 SQL Server 表 COLUMN 中,并获取有关从文件夹加载的各种 XML 文件的信息。结果我不确定如何使用变量来运行这个包。

  • 谁能首先帮助我如何正确参数化文件名?

  • 以及稍后如何配置 ForEachLoop 容器以从文件夹中读取每个文件?

我对如何在这种情况下使用用户变量感到困惑。

4

1 回答 1

1

首先我创建一个表来存储 XML:

CREATE TABLE XMLstore (
    IncomingXMLfile xml,
    ImportDate datetime
)

为测试目的创建 2 个文件,ABC.xmlDEF.xml在其中放入一些 XML 内容:

<some>
    <row id="1">
        <stuff>1</stuff>
    </row>
</some>

然后运行这个脚本:

DECLARE @command varchar(1000),
        @dir varchar(max) = 'D:\API_Schemas\',
        @n int = 0,
        @i int = 1,
        @sql nvarchar(max)

DECLARE @files TABLE (
    id INT IDENTITY(1,1),
    files varchar(1000)
)

SET @command = 'dir "'+ @dir +'" /B'

INSERT INTO @files (files)
EXEC xp_cmdshell @command

SELECT @n = COUNT(*) 
FROM @files
WHERE files like '%.xml%'

WHILE @n >= @i
BEGIN

    SELECT @sql = N'
    INSERT INTO XMLstore (IncomingXMLfile, ImportDate)
    SELECT  CONVERT(XML, BulkColumn) AS BulkColumn, GETDATE() 
    FROM OPENROWSET(BULK '''+@dir+files+''', SINGLE_BLOB) AS x;'
    FROM @files
    WHERE id = @i

    EXEC sp_executesql @sql

    SET @i = @i + 1
END

之后,我从表中选择XMLstore

SELECT *
FROM XMLstore

并获得输出:

IncomingXMLfile                                 ImportDate
<some><row id="1"><stuff>1</stuff></row></some> 2016-10-06 10:17:41.453
<some><row id="2"><stuff>2</stuff></row></some> 2016-10-06 10:17:41.457

描述:

文件存储在这里D:\API_Schemas\。我使用xp_cmdshell运行命令dir "D:\API_Schemas\" /B从该目录中获取所有文件。

/B用于启用

使用裸格式(没有标题信息或摘要)

所以我们只得到文件名。并把它们放在@files桌子上。

id该表具有从1每一行(文件)开始添加的标识列。所以我们可以使用简单的计数器 ( ) 来迭代 throw while 循环@i

在 while 循环中,我们创建一个动态 SQL 查询并运行它。

笔记:

而不是xp_cmdshell你可以使用xp_dirtree(它是无证和不受支持的),如:

DECLARE @dir varchar(100) = 'D:\API_Schemas\'

DECLARE @files TABLE (
    id INT IDENTITY(1,1),
    files varchar(1000),
    depth int,
    [file]  int
)

INSERT INTO @files 
EXEC xp_dirtree @dir, 1, 1
于 2016-10-06T07:18:29.750 回答