【问题标题】:Save/log the value of a variable in SSIS for the next execution在 SSIS 中保存/记录变量的值以供下次执行
【发布时间】:2019-07-18 21:56:30
【问题描述】:

我目前正在将数据库中的数据导出到 XML 文件中。这很好用。根据数据量,一个 XML 文件仅包含一个或数百个数据集。这个过程每天都会触发。现在数据集应该有一个像“FileNo”这样的属性,它应该在开始时为零,然后总是增加值一。现在我看到SSIS中有foreach-containers和for-containers。不幸的是,我担心使用这样的容器会每天为所有数据集提供相同的“FileNo”,因此它们并非都被正确提升。此外,我不知道是否可以在 SSIS 中将变量“FileNo”的最后一个值缓存在某处,以便第二天可以使用“FileNo”的下一个更高的值,而不是从零重新开始。 ..

您知道如何计算这样一个变量并将其存储在某个地方,以便在第二天再次调用它吗?所以最后它应该是这样的:

感谢您的帮助。

【问题讨论】:

  • 如果你可以在 SSIS 中获取当前的 FileNo(听起来你就是这样迭代它并将它放在一个变量中)。一旦进入 SSIS 包末尾的变量,您就可以将 FileNo 保存在某处。到数据库,到平面文件/配置文件。然后,当您找到它时,将 SSIS 预运行其他文件中的 FileNo 变量设置为您查找的文件。然后在 SSIS 开始时首先查看该数据库或平面文件(如果它不存在,则从 0 开始)
  • 我会创建一个日志表,您可以在其中跟踪执行次数(以及可能的其他有用数据,如时间戳和/或成功标志)。然后,您可以为每次执行插入一个新行并跟踪它们。
  • fileNo 的用途是什么?我似乎没有任何价值,甚至可能会混淆 XML 的最终用户。它看起来像一把钥匙,但它是一个随机数,不会与任何东西联系起来。

标签: xml for-loop foreach ssis etl


【解决方案1】:

我将尝试将您的问题分为两部分:

  1. 在每个循环中增加变量 FileNo
  2. 存储最新的文件值

在每个循环中增加变量 FileNo

要在每个循环中增加值,最简单的方法是在 foreach 循环容器中使用表达式任务,使用类似的表达式:

@[User::FileNo] = @[User::FileNo] + 1

更多信息可以参考以下答案:

存储最新的文件值

不幸的是,没有选项可以将此值存储在 SSIS 包中,但您可以将其存储在数据库或文本文件中,并在包执行开始时检索它并在结束时更新此值。

如果您决定将值存储在数据库中,则需要使用执行 SQL 任务。如果您决定使用平面文件,那么您必须使用脚本任务编写脚本以在开头检索值并在结尾存储它。

我将提供一些可能有助于实施此过程的链接:

从数据库中读取值

使用 c# 从平面文件中读取和存储值

【讨论】:

    【解决方案2】:

    C# 脚本任务可用于检索最后一个 FileNo 值。完成此操作后,可以更新 SSIS 变量以保存它,您可以通过将其记录到表或其他方法来存储它。另一种选择是直接存储在脚本任务中的表中。下面概述了这两个选项。在脚本中,DateTime.Now 属性也存储为时间戳。下面的示例介绍了使用LINQLastOrDefault 方法从XML 元素和属性中获取最后一个FileNo。如果没有找到任何元素,此方法返回默认值,而 Last 方法在这种情况下会抛出错误。使用的 XML 路径当然是一个示例,需要更改为您的路径。

    using System.Data;
    using System.Data.SqlClient;
    using System.Linq;
    using System.Xml.Linq;
    
    
    string xmlFile = Dts.Variables["User::XMLFilePath"].Value.ToString();  
    
    //load xml document       
    XDocument xmlDoc = XDocument.Load(xmlFile);
    
    //get last FileNo value
    string lastFileNoElement = xmlDoc.Elements("Root").Elements("Element1").
                        Elements("Element2").Elements("FileNo").LastOrDefault().Value.ToString();
    string lastFileNoAttribute = xmlDoc.Elements("Root").Elements("Element1")
                        .Elements("Element2").Attributes("FileNo").LastOrDefault().Value.ToString();
    
    //update ssis variable (element)
    Dts.Variables["User::FileNoElement"].Value = lastFileNoElement;
    //update ssis variable (attribute)
    Dts.Variables["User::FileNoAttribute"].Value = lastFileNoAttribute;
    
    //create connection
    string connStr = @"Data Source=YourServer;Initial Catalog=Database;Integrated Security=true";
    string cmd = "INSERT INTO Schema.LoggingTable (FileNoAttribute, FileNoElement, ExecutionTime) values(@atName, @eleName, @execTime)";
    using (SqlConnection conn = new SqlConnection(connStr))
    {
        SqlCommand sql = new SqlCommand(cmd, conn);
        //attribute parameter
        SqlParameter aParam = new SqlParameter("@atName", SqlDbType.VarChar);
        aParam.Size = 50;
        aParam.Direction = ParameterDirection.Input;
        aParam.Value = lastFileNoAttribute;
        //element parameter
        SqlParameter eParam = new SqlParameter("@eleName", SqlDbType.VarChar);
        eParam.Size = 50;
        eParam.Direction = ParameterDirection.Input;
        eParam.Value = lastFileNoElement;
    
        //timestamp
        SqlParameter dateParam = new SqlParameter("@execTime", SqlDbType.DateTime);
        dateParam.Direction = ParameterDirection.Input;
        dateParam.Value = DateTime.Now;
    
        sql.Parameters.Add(aParam);
        sql.Parameters.Add(eParam);
        sql.Parameters.Add(dateParam);
    
        conn.Open();
        //insert data
        sql.ExecuteNonQuery();
    }
    

    【讨论】:

      最近更新 更多