【问题标题】:SSIS Excel Import - Worksheet variable OR wildcard?SSIS Excel导入 - 工作表变量或通配符?
【发布时间】:2018-01-25 02:58:06
【问题描述】:

我有一个 SSIS 数据导入包,它使用源 Excel 电子表格,然后将数据导入 SQL Server 数据库表。由于 Excel 文件的工作表名称每天都在更改,因此我未能成功实现此过程的自动化。因此,我必须在每天运行导入之前手动更改工作表名称。需要注意的是,永远不会有任何其他工作表。

我可以为工作表名称创建一个变量吗? 我可以使用通配符而不是工作表名称吗? 在启动导入作业之前创建 Excel 宏或类似方法来更改工作表名称会更好吗?

【问题讨论】:

    标签: sql-server excel ssis wildcard worksheet


    【解决方案1】:

    这对我来说非常适合相同的场景,以防它帮助你或其他人:

    必需的包级字符串变量 2:

    • varDirectoryList - 您将在 SSIS 中为每个循环变量映射使用它

    • varWorkSheet - 这将保存您更改的工作表名称。既然你只有 1 个,那就完美了。

    设置:

    • 一个。为每个循环添加 SSIS
    • 乙。 Excel 连接管理器(在您测试时连接到第一个工作簿,然后在最后您将转到属性并在您的 varDirectoryList 中添加表达式“Excel 文件路径”。将 DelayValidation 设置为 True 以及您的 Excel 源任务。*这将有助于它进行通过文件夹中的每个工作簿)
    • c。在您的 For Each 循环中添加一个 Scrip Task C#,将其命名为“获取更改工作表 命名为变量”或您的偏好。
    • 使用 Excel 源到 SQL 表目标的数据流任务。

    在您的脚本任务中添加以下代码:

    using System.Data.OleDb;
    
    
        public void Main()
        {
            // store file name passed into Script Task
            string WorkbookFileName = Dts.Variables["User::varDirectoryList"].Value.ToString();
    
            // setup connection string
            string connStr = String.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"EXCEL 12.0;HDR=Yes;IMEX=1;\"", WorkbookFileName);
    
            // setup connection to Workbook
            using (var conn = new OleDbConnection(connStr))
            {
                try
                {
                    // connect to Workbook
                    conn.Open();
    
                    // get Workbook schema
                    using (DataTable worksheets = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null))
                    {
                        // in ReadWrite variable passed into Script Task, store third column in the first 
                        // row of the DataTable which contains the name of the first Worksheet
                        Dts.Variables["User::varWorkSheet"].Value = worksheets.Rows[0][2].ToString();
    
                        //Uncomment to view first worksheet name of excel file. For testing purposes.
                        MessageBox.Show(Dts.Variables["User::varWorkSheet"].Value.ToString());
                    }
                }
                catch (Exception)
                {
                    throw;
                }
            }
    
    
        }
    

    设置并运行此设置后,您将收到一个消息框,其中显示每个工作簿的更改工作表名称。

    • 如果您使用 Excel 源 SQL 命令,则需要第三个字符串 变量如:varExcelSQL 和其中的表达式如:SELECT 来自 ['varWorkSheet$'] 的列将动态更改以匹配 每个工作簿。您可能需要也可能不需要单引号,更改为 在 varExcelSQL 中需要。
    • 如果您不使用 Excel Source SQL 并且直接从 桌子;进入 Excel 源属性 --> AccessMode --> OpenRowSet from Variable --> 选择 varWorkSheet。

    只要列结构保持不变,就应该解决它。

    如果您碰巧在一列中有多种数据类型的文件;您可以在连接字符串中使用 IMEX=1,这会在导入时强制数据类型为 DT_WSTR。

    希望这会有所帮助:-)

    【讨论】:

      【解决方案2】:

      我使用以下脚本任务(C#):

      System.Data.OleDb.OleDbConnection objConn;
      DataTable dt;
      
      string connStr = ""; //Use the same connection string that you have in your package
      objConn = new System.Data.OleDb.OleDbConnection(ConnStr);
      objConn.Open();
      
      dt = objConn.GetOleDbSchemaTable(System.Data.OleDb.OleDbShemaGuid.Tables,null);
      objConn.Close();
      
      foreach(DataRow r in dt.Rows)
      {
         //for some reason there is always a duplicate sheet with underscore.
         string t = r["TABLE_NAME"].ToString(); 
      
         //Note if more than one sheet exist this will only capture the last one
         if(t.Substring(t.Length-1)!="_")
         {
             Dts.Variables["YourVariable"].Value = t;
         }
      }
      

      然后在 SSIS 中,我添加另一个变量来构建我的 SQL。

      新变量“Select * from [”+“你的变量”+“]”

      最后将您的数据源设置为 Excel 源中的那个 SQL 变量。

      【讨论】:

        【解决方案3】:

        如果您使用 SSIS 导入工作表,您可以使用脚本任务来查找工作表的名称,然后更改名称或您需要执行的任何其他操作以使其适合导入的其余部分。以下是查找我找到的工作表的示例here

        Dim excel As New Microsoft.Office.Interop. Excel.ApplicationClass
        Dim wBook As Microsoft.Office.Interop. Excel.Workbook
        Dim wSheet As Microsoft.Office.Interop. Excel.Worksheet
        
        wBook = excel.Workbooks.Open 
        wSheet = wBook.ActiveSheet()
        
        For Each wSheet In wBook.Sheets
        MsgBox(wSheet.Name)  
        Next
        

        在 MsgBox 行中,您可以更改名称或将其报告给另一个进程

        【讨论】:

        • 我使用过类似的 C#,但我需要过滤掉带有下划线的额外表格。