You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何自动将SFTP文件夹中的XML文件导入SQL Server数据库?

需求:自动将SFTP中新传入的XML文件导入SQL Server数据库

目前已通过SQL查询使用OPENROWSET实现手动处理数据,但OPENROWSET不允许使用变量定义待导入文件的名称/路径。现有手动处理代码如下:

WITH rs (xmlData) AS
(
   SELECT TRY_CAST(BulkColumn AS XML) 
   FROM OPENROWSET(BULK N'C:\Users\SFLYNN01\Desktop\jobStatusUpdate-C158788-20231017161702.xml', SINGLE_BLOB) AS x
)
SELECT 
      c.value('(JobRef/text())[1]', 'VARCHAR(20)')AS JobRef
    , c.value('(Stages[Type/text()="1"]/Address/AddressCode/text())[1]', 'VARCHAR(20)')AS ColCode
    , c.value('(Stages[Type/text()="1"]/DateTimeFrom/text())[1]', 'DATE') AS ColDate
    , c.value('(Stages[Type/text()="1"]/DateTimeFrom/text())[1]', 'TIME') AS ColTime
    , c.value('(Stages[Type/text()="2"]/Address/AddressCode/text())[1]', 'VARCHAR(20)')AS DelCode
    , c.value('(Stages[Type/text()="2"]/DateTimeFrom/text())[1]', 'DATE') AS DelDate
    , c.value('(Stages[Type/text()="2"]/DateTimeFrom/text())[1]', 'TIME') AS DelTime
    , c.value('(Response/JobTrackingURL/text())[1]', 'VARCHAR(20)')AS TrackingURL
    , c.value('(statusId/text())[1]', 'VARCHAR(20)')AS Status
FROM 
    rs
CROSS APPLY 
    xmldata.nodes('/job') AS t(c)

现需要可自动处理SFTP文件夹中新传入XML文件的方案,因文件数量过多无法手动处理。


可行解决方案

方案1:动态SQL + SQL Server代理作业

步骤:

  • 编写存储过程,通过动态SQL拼接OPENROWSET路径,遍历本地临时目录(需先从SFTP下载文件到该目录)的XML文件:
CREATE PROCEDURE dbo.ImportXMLFiles
AS
BEGIN
    SET NOCOUNT ON;
    DECLARE @FilePath NVARCHAR(500), @SQL NVARCHAR(MAX);
    -- 临时表存储文件列表
    CREATE TABLE #Files (FileName NVARCHAR(500));
    -- 读取指定目录下的XML文件
    INSERT INTO #Files
    EXEC xp_cmdshell 'dir "C:\SFTP_Downloads\*.xml" /b';

    DECLARE file_cursor CURSOR FOR
    SELECT FileName FROM #Files WHERE FileName IS NOT NULL;

    OPEN file_cursor;
    FETCH NEXT FROM file_cursor INTO @FilePath;

    WHILE @@FETCH_STATUS = 0
    BEGIN
        SET @SQL = N'
        WITH rs (xmlData) AS
        (
           SELECT TRY_CAST(BulkColumn AS XML) 
           FROM OPENROWSET(BULK N''C:\SFTP_Downloads\' + @FilePath + ''', SINGLE_BLOB) AS x
        )
        INSERT INTO YourTargetTable (JobRef, ColCode, ColDate, ColTime, DelCode, DelDate, DelTime, TrackingURL, Status)
        SELECT 
              c.value(''(JobRef/text())[1]'', ''VARCHAR(20)'')AS JobRef
            , c.value(''(Stages[Type/text()="1"]/Address/AddressCode/text())[1]'', ''VARCHAR(20)'')AS ColCode
            , c.value(''(Stages[Type/text()="1"]/DateTimeFrom/text())[1]'', ''DATE'') AS ColDate
            , c.value(''(Stages[Type/text()="1"]/DateTimeFrom/text())[1]'', ''TIME'') AS ColTime
            , c.value(''(Stages[Type/text()="2"]/Address/AddressCode/text())[1]'', ''VARCHAR(20)'')AS DelCode
            , c.value(''(Stages[Type/text()="2"]/DateTimeFrom/text())[1]'', ''DATE'') AS DelDate
            , c.value(''(Stages[Type/text()="2"]/DateTimeFrom/text())[1]'', ''TIME'') AS DelTime
            , c.value(''(Response/JobTrackingURL/text())[1]'', ''VARCHAR(20)'')AS TrackingURL
            , c.value(''(statusId/text())[1]'', ''VARCHAR(20)'')AS Status
        FROM 
            rs
        CROSS APPLY 
            xmldata.nodes(''/job'') AS t(c)';
        EXEC sp_executesql @SQL;

        -- 导入后将文件移至归档目录
        EXEC xp_cmdshell 'move "C:\SFTP_Downloads\' + @FilePath + '" "C:\SFTP_Archive\"';

        FETCH NEXT FROM file_cursor INTO @FilePath;
    END

    CLOSE file_cursor;
    DEALLOCATE file_cursor;
    DROP TABLE #Files;
END
  • 配置SQL Server代理作业,定期执行该存储过程;同时添加PowerShell脚本步骤,自动从SFTP下载新文件到本地目录,确保作业账户拥有SFTP访问、文件系统读写和SQL Server操作权限。

方案2:SSIS(SQL Server Integration Services)

步骤:

  • 创建SSIS包,添加SFTP任务从远程服务器下载新XML文件到本地目录。
  • 添加Foreach循环容器,遍历本地目录中的XML文件。
  • 在循环内添加XML源组件,通过XPath提取所需字段,映射到SQL Server目标表完成导入。
  • 添加文件移动任务,将已处理文件移至归档目录避免重复导入。
  • 将SSIS包部署到SSIS目录,通过SQL Server代理定期执行,或借助自定义脚本监控目录实现文件触发执行。

方案3:PowerShell脚本自动化

步骤:

  • 编写PowerShell脚本,整合SFTP下载、文件遍历、SQL导入逻辑:
# 加载WinSCP组件(需预先安装WinSCP .NET Assembly)
Add-Type -Path "C:\Program Files (x86)\WinSCP\WinSCPnet.dll"

# SFTP连接配置
$sessionOptions = New-Object WinSCP.SessionOptions -Property @{
    Protocol = [WinSCP.Protocol]::Sftp
    HostName = "your-sftp-server.com"
    UserName = "sftp-user"
    Password = "sftp-password"
    SshHostKeyFingerprint = "ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx"
}

$session = New-Object WinSCP.Session
try {
    $session.Open($sessionOptions)
    # 下载SFTP上的新XML文件到本地
    $transferOptions = New-Object WinSCP.TransferOptions
    $transferOptions.TransferMode = [WinSCP.TransferMode]::Binary
    $transferResult = $session.GetFiles("/remote-sftp-path/*.xml", "C:\Local_XML_Files\")
    
    # 遍历已下载文件并导入SQL
    foreach ($file in $transferResult.Transfers) {
        $localPath = $file.Destination
        $sql = @"
WITH rs (xmlData) AS
(
   SELECT TRY_CAST(BulkColumn AS XML) 
   FROM OPENROWSET(BULK N'$localPath', SINGLE_BLOB) AS x
)
INSERT INTO YourTargetTable (JobRef, ColCode, ColDate, ColTime, DelCode, DelDate, DelTime, TrackingURL, Status)
SELECT 
      c.value('(JobRef/text())[1]', 'VARCHAR(20)')AS JobRef
    , c.value('(Stages[Type/text()="1"]/Address/AddressCode/text())[1]', 'VARCHAR(20)')AS ColCode
    , c.value('(Stages[Type/text()="1"]/DateTimeFrom/text())[1]', 'DATE') AS ColDate
    , c.value('(Stages[Type/text()="1"]/DateTimeFrom/text())[1]', 'TIME') AS ColTime
    , c.value('(Stages[Type/text()="2"]/Address/AddressCode/text())[1]', 'VARCHAR(20)')AS DelCode
    , c.value('(Stages[Type/text()="2"]/DateTimeFrom/text())[1]', 'DATE') AS DelDate
    , c.value('(Stages[Type/text()="2"]/DateTimeFrom/text())[1]', 'TIME') AS DelTime
    , c.value('(Response/JobTrackingURL/text())[1]', 'VARCHAR(20)')AS TrackingURL
    , c.value('(statusId/text())[1]', 'VARCHAR(20)')AS Status
FROM 
    rs
CROSS APPLY 
    xmldata.nodes('/job') AS t(c)
"@
        Invoke-SqlCmd -ServerInstance "YourSQLServer" -Database "YourDB" -Query $sql
        
        # 移至归档目录
        Move-Item -Path $localPath -Destination "C:\XML_Archive\"
    }
} finally {
    $session.Dispose()
}
  • 将脚本设置为Windows定时任务,定期执行,确保执行账户拥有SFTP访问、文件系统读写和SQL Server操作权限。

内容的提问来源于stack exchange,提问作者steve_flynn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 20:17:30