通过SSIS获取SFTP或FTPS文件的最佳方法

时间:2009-01-03 18:03:40

标签: ssis service integration sftp ftps

这个问题最初询问哪种是在SSIS中通过SFTP或FTPS上传文件的最佳方法。现在只列出每种解决方案的优缺点。我个人现在使用CozyRoc的SFTP库,但我已经在以下某个方面使用了以下每个解决方案。

SSIS组件库

方法:从每个开发和生产服务器上的CozyRocCodeplexBizCryptoPragmaticWorks或其他供应商安装SSIS组件库,并使用SFTP任务上传文件。

优点:易于使用。它看起来,闻起来和感觉就像一个正常的SSIS任务。 SSIS还将密码识别为敏感信息,并允许您保护敏感信息的所有常规选项,而不是仅以非安全方式将其存储为明文。适用于其他SSIS任务,例如ForEach Loop Containers。上传和下载失败时出错。如果您不知道要下载的远程FTP站点上的文件名称,或者在运行时之前您不知道要上载的文件的名称,则可以正常工作。

缺点:除了Codeplex解决方案之外,这需要花费在生产环境中许可。需要在每台开发和生产计算机上安装库。如果是Codeplex解决方案,那么您使用的是任何特定供应商都不支持的软件。这也使您依赖供应商在每个版本之间更新其库。例如,在2008 RTM之前,我在2008年的CTP版本上开发了一个新服务器,而CozyRoc 2005库与它不兼容。最终他们发布了2008兼容版本,但我不得不暂时使用命令行解决方案来解决这个问题。

命令行SFTP计划

方法:安装免费的命令行SFTP应用程序,如Putty和WinSCP,并通过运行批处理文件或操作系统进程任务来执行它。有关通过WinSCP执行此操作的说明,请列出here

优点:免费,免费,免费。如果您使用Putty,您可以确定它是安全的,因为许多GUI FTP客户端似乎使用Putty。您肯定知道您使用的是SSH2而不是SSH。

缺点:我尝试过的两个命令行实用程序(Putty和Cygwin)需要将SFTP密码存储在非安全位置。我没有找到一种在上传文件时捕获失败或错误的好方法。这个过程看起来并不像SSIS。大多数代码都封装在文本文件中而不是SSIS本身。如果您不知道要上传或下载的文件的确切名称,则很难使用。

3RD PARTY C#或VB.NET LIBRARY

方法:安装SFTP或FTPS库并使用引用该库的脚本任务来上载文件。 (我从未尝试过这个,所以我会猜测它的优点和缺点)

优点:可能很容易捕获错误。应该适用于变量,因此即使您不知道要上传或下载的文件的确切名称,它也可能很容易使用。

缺点:这是一个结合.NET库的脚本任务。如果您正在使用SSIS,那么您可能更熟悉SSIS任务,然后是.NET代码。脚本任务也很难排除故障,因为它们没有与常规.NET项目相同的调试工具和功能。创建对第三方代码的依赖关系,这些代码可能在不同版本的SQL Server之间不起作用。公平地说,它可能更有可能在不同版本的SQL Server之间工作,而不是第三方SSIS任务库。另一个巨大的骗局 - 我还没有找到一个免费的C#或VB.NET库。所以,如果有人知道,请告诉我!

3 个答案:

答案 0 :(得分:9)

以下问题可能有用:

What would be a recommended choice of SSIS component to perform SFTP or FTPS task?

<强> Cozyroc:

通过将服务器设置为“仅允许SSHv2”并进行测试,可以轻松测试ssh协议的可用性。您是否尝试过询问Cozy的销售部门?

命令行sftp:

未知文件名问题可以解决简单脚本/使用通配符(至少在Cygwin下)。

第三方lib:

为什么需要FTPS的第三方lib? .NET从2.0开始就支持这个协议。

http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest.enablessl.aspx

答案 1 :(得分:2)

我只想提供一份有关解决SSIS中SFTP问题的实际决定的更新。这是发生的事情的细分:

  1. 我最初尝试使用Putty和一些批处理文件来上传文件,但很难捕获错误。此外,我将SFTP凭证存储在明文文件中,因为它是Putty上传脚本的一部分。

  2. 我们为SSIS服务器购买了CozyRoc许可证,每年花费数百美元,我对使用他们产品的结果感到非常满意。使用CozyRoc的产品,如果上传有任何问题,控制流任务会引发错误。由于我的团队中还有几个初级SSIS程序员,因此他们更容易理解如何设置控制流任务而不是使用Putty脚本方法。最后,密码使用SSIS的本机加密进行加密,以保护敏感数据。我的服务器上不再以明文形式存储任何密码。

  3. 我确实回顾了这个问题中推荐的其他一些第三方库,但看起来CozyRoc是供应商中最便宜的,他们还有一些其他SSIS任务我可以在我的BI团队中使用。谢谢,CozyRoc!

答案 2 :(得分:-3)

没有组件,您可以使用脚本任务。见this link

Imports System
Imports Microsoft.SqlServer.Dts.Runtime
Imports Ftp
Imports System.IO

Public Class ScriptMain

    Public Sub Main()

        Try

            Dim cm As ConnectionManager = Dts.Connections.Add("FTP")
            cm.Properties("ServerName").SetValue(cm, Dts.Variables("SFTPServerName").Value.ToString)
            cm.Properties("ServerUserName").SetValue(cm, Dts.Variables("SFTPLogin").Value.ToString)
            cm.Properties("ServerPassword").SetValue(cm, Dts.Variables("SFTPPassword").Value.ToString)
            cm.Properties("ServerPort").SetValue(cm, Dts.Variables("SFTPPortNumber").Value.ToString)
            cm.Properties("Timeout").SetValue(cm, "0")
            cm.Properties("ChunkSize").SetValue(cm, "0") '1000 kb
            cm.Properties("Retries").SetValue(cm, "0")
            Dts.Variables("Continue").Value = 0

            Dim ftp As FtpClientConnection = New FtpClientConnection(cm.AcquireConnection(Nothing))
            Dim FilesList() As String
            Dim FolderName() As String

            Dim Separator As String = ";"
' \\ServerName\Share1;\\ServerName\Share2 : Local copy
            Dim FolderLocalListSrc As String = Dts.Variables("FolderLocalListSrc").Value.ToString
            Dim FolderLocalListDst() As String = Split(FolderLocalListSrc, Separator)
            Dim Counter As Integer

            ftp.Connect()
            ftp.GetListing(FolderName, FilesList)

            If FilesList IsNot Nothing Then

                Dim FileName As String

                For Each FileName In FilesList

                    Dim FileToProcess(0) As String
                    Dim FileToMove(0) As String

                    For Counter = 0 To FolderLocalListDst.GetUpperBound(0)

                        FileToProcess(0) = FileName
                        FileToMove(0) = FolderLocalListDst(Counter) + FileName

                        If (File.Exists(FileToMove(0)) = False) Then

                            ' Téléchargement en local
                            ftp.ReceiveFiles(FileToProcess, FolderLocalListDst(Counter), True, True)

                        End If

                    Next

                    ' Upload du fichier dans les archives du FTP
                    ftp.SendFiles(FileToMove, "/Archives", True, False)

                    ' Suppression du fichier à la racine du FTP
                    ftp.DeleteFiles(FileToProcess)

                Next

            End If

            ftp.Close()

            Dts.TaskResult = Dts.Results.Success
        Catch ex As Exception
            Dts.TaskResult = Dts.Results.Failure
        End Try

    End Sub

End Class