1

我正在创建一个理想情况下的 SSIS 包:

  • 通读文件夹
  • 获取最新文件的文件名和工作表名
  • 将文件名和工作表名称传递给连接管理器
  • 仅逐张提取最新文件并将其加载到数据库中

该文件夹将使用文件的最新版本定期更新。有问题的文件将有 3 张纸,按特定顺序依次加载。最好我想通过文件的最新写入时间来获取文件,而不是使用文件名。每次上传的文件名本身都会不同。

我创建了一个控制流,它在将工作表加载到数据库中时以正确的顺序进行提取和加载,但是它只从 Excel 连接管理器中的指定文件中读取:

  • Sheet1:Excel 源 -> OLE DB 目标
  • Sheet2:Excel 源 -> OLE DB 目标
  • Sheet3:Excel 源 -> OLE DB 目标

我发现涉及将文件名作为变量传递给连接管理器,但我发现没有任何示例也考虑工作表名称。有人可以帮助我使这个更有活力吗?

我正在使用 SQL Server 2012 并在 Visual Studio 2010 中进行设计。

4

2 回答 2

0

我可以帮助您获取 VS 2008 中的工作表名称(2010 年可能相同)。

创建 Object 类型的变量 (objExcelSheets) 创建脚本任务。将文件名/路径变量添加到脚本(只读) 将对象变量添加到读写变量

这是脚本任务的一些代码

Private Sub GetExcelSheets()
    Dim excelFile, connstr, curTable As String
    Dim excelConnection As OleDb.OleDbConnection
    Dim tablesInFile As DataTable
    Dim tablenameInFile As DataRow
    Dim tableCount As Integer = 0
    Dim tableIndex As Integer = 0
    Dim excelTables As String()
    Dim blnFound As Boolean = False

    ReDim excelTables(0)
    excelFile = Dts.Variables("sFilePath").Value.ToString
    connstr = GetExcelConnString()

    excelConnection = New OleDb.OleDbConnection(connstr)
    excelConnection.Open()

    tablesInFile = excelConnection.GetSchema("Tables")
    tableCount = tablesInFile.Rows.Count

    For Each tablenameInFile In tablesInFile.Rows
        curTable = tablenameInFile.Item("TABLE_NAME").ToString.Trim.ToLower

        If curTable.IndexOf("SOMETHING_IN_THE_SHEETS_TO_PROCESS") >= 0 Then
            blnFound = True
            ReDim excelTables(tableIndex)
            excelTables(tableIndex) = "[" + curTable + "]"
            tableIndex += 1
        End If
    Next

    If IsNothing(excelTables(0)) Then excelTables(0) = String.Empty

    excelConnection.Close()

    Dts.Variables("objExcelSheet").Value = excelTables
End Sub

Private Function GetExcelConnString() As String
    Dim sExtendedProperties, sExtension, sFilePath, sExcelConn As String

    sFilePath = Dts.Variables("sFilePath").Value.ToString
    sExtension = sFilePath.Substring(sFilePath.LastIndexOf("."))
    If sExtension.ToLower = ".xlsx" Then
        sExtendedProperties = ";Extended Properties=""EXCEL 12.0;HDR=NO"";"
    ElseIf sExtension.ToLower = ".xls" Then
        sExtendedProperties = ";Extended Properties=""EXCEL 8.0;HDR=NO;IMEX=1"";"
    Else
        sExtendedProperties = String.Empty
    End If

    sExcelConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & sFilePath & sExtendedProperties

    Return sExcelConn
End Function

请注意,这需要安装 ACE 驱动程序,如果您没有这些驱动程序,则需要将 sExcelConn 替换为文件的连接字符串。

这会将工作表名称中带有 SOMETHING_IN_THE_SHEETS_TO_PROCESS 的所有 Excel 工作表放入对象变量 objExcelSheet。您可以将其替换为您需要的任何内容或将其全部删除。

然后,您可以执行 ForEach 循环来处理每张纸。

来自变量枚举器的 Foreach - 变量 = objExcelSheet

变量映射 - 变量(索引为 0 的工作表名称)

这应该可以帮助您获得所需的内容,您可以在其中动态选择要处理的工作表并从那里做您需要做的事情。

于 2013-11-13T22:05:05.277 回答
0

我有更好的方法而不是 script task 。对于不懂 C# 或 VB.net 的人来说,编写脚本并不容易,所以另一种方法是使用 WMI watcher。如果有新文件,它将持续监视文件夹,它将启动包并将文件信息(如 fileName)存储到 sql server 中。另一种方法是使用 cmd 作为 sql 表的文件名,在执行包后,它将删除或存档该文件,因此我们将始终在该文件夹中拥有一个新文件。我在我的一个项目中做同样的事情。

于 2019-10-05T08:17:33.853 回答