2016-10-06 44 views
2

今天,我有一個新的情況,即從客戶端要求如下:在SSIS 2012 - 從文件加載XML文件到SQL Server表列,使用執行SQL任務和foreach循環容器

我們的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())和文件本身的名稱(我沒有提到此列現在在INSERT語句中)。我必須使用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任務,我得到這個錯誤:

"Parameter name is unrecognized.". Possible failure reasons: Problems with the query, "ResultSet" property not set correctly, parameters not set correctly, or connection not established correctly.

這種情況是相當不同的,當我加載從XML文件(使用XML源代碼編輯器中的數據,與數據訪問模式(自變量的XML數據)等)到SQL Server表中。在我們的例子中,我們將XML文件本身加載到具有XML數據類型的SQL Server表COLUMN中,並獲取有關從文件夾加載的各種XML文件的信息。因此我不確定如何使用變量來運行此包。

  • 任何人都可以首先幫助我如何正確地參數化文件名?

  • 稍後介紹如何配置ForEachLoop容器從文件夾中讀取每個文件?

我很困惑如何在這種情況下使用用戶變量。

+0

最直接的方法是使用動態SQL在while循環。從文件夾獲取文件列表到臨時表中,首先,生成查詢運行到第二個...等等,甚至生成一個大的語句並立即運行它。 – gofr1

+0

你能否提供一個關於如何在這種情況下使用動態SQL的例子?我在各種情況下都使用了動態SQL,但不是像這樣的情況。 – user3812887

+0

我使用動態SQL添加解決方案作爲答案。 – gofr1

回答

0

起初,我創建一個表來存儲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 '''[email protected]+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用於啓用

Uses bare format (no heading information or summary)

,所以我們只得到文件名。並把它們放到@files表中。

這張表得到了標識列,其中添加了從1開始的id到每一行(文件)。所以我們可以使用簡單的計數器循環拋出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 
相關問題