Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server SSIS 2012-条件标头';位置_Sql Server_Ssis_Ssis 2012 - Fatal编程技术网

Sql server SSIS 2012-条件标头';位置

Sql server SSIS 2012-条件标头';位置,sql-server,ssis,ssis-2012,Sql Server,Ssis,Ssis 2012,我需要使用SSI将数千个txt文件暂存到SQL Server 2012实例中 问题是一些txt文件的前两行中有控制校验和,而另一些则没有 如果一个文件有校验和,它的第一行以“HEADER”开头——在这种情况下,我必须跳过前两行,然后从第3行读取列标题,并从第4行开始加载数据 如果文件没有校验和,列名称将存在于第#1行,数据从第#2行开始 现在,我的问题是:处理这种情况的最不具侵入性的方式是什么?我很懒,所以我在寻找最小的努力和最大的效果 到目前为止,我的想法是: 使用C#脚本组件检测校验和的存在

我需要使用SSI将数千个txt文件暂存到SQL Server 2012实例中

问题是一些txt文件的前两行中有控制校验和,而另一些则没有

如果一个文件有校验和,它的第一行以“HEADER”开头——在这种情况下,我必须跳过前两行,然后从第3行读取列标题,并从第4行开始加载数据

如果文件没有校验和,列名称将存在于第#1行,数据从第#2行开始

现在,我的问题是:处理这种情况的最不具侵入性的方式是什么?我很懒,所以我在寻找最小的努力和最大的效果

到目前为止,我的想法是:

  • 使用C#脚本组件检测校验和的存在,并构建两个单独的流,每种文件类型一个。缺点:两个几乎相同的流(我不太喜欢冗余)

  • 在运行SSIS流之前,请先使用PowerShell清除文件中的校验和。缺点:需要重新写入大量文件(性能下降)

  • 询问StackOverflow。缺点:可以被StackOverflow社区视为讽刺

  • 有什么提示吗?

    这里有一个方法

  • 创建两个平面文件连接管理器,在设计模式下,浏览到每个平面文件的示例文件,以便设置列等
  • 对于没有校验和行的平面文件连接管理器,将要跳过的
    标题行保留为0,对于具有校验和行的平面文件连接管理器,将其设置为跳过前两行,如下所示。
    
  • 将两个连接管理器的
    DelayValidation
    属性设置为
    true
  • 在数据流任务中,使用脚本组件检测文件是否有校验和行
  • 在脚本组件的输出中,将文件的完整路径作为输出列,并具有指示文件是否具有校验和行的标志。例如:
    HasCheckSumRows
  • 将脚本组件的输出连接到条件拆分任务
  • 在条件拆分任务中,根据设置为
    true
    hasschecksumrows
    标志进行拆分,并创建两个输出,一个用于带校验和行的文件,另一个用于不带校验和行的文件
  • 创建两个平面文件源,一个用于校验和行文件,使用为这些类型的文件创建的平面文件连接管理器,另一个用于不带校验和行的常规文件
  • 使用输出列中的完整文件路径作为平面文件源的
    connectionstring
    ,将条件拆分的2个输出连接到相应的平面文件源
  • 最后,使用UNIONALL组件将两种类型的文件中的行返回到1个输入数据流中。因此,这不会复制您的工作流(即不会导致冗余),因为您的所有行都在一个流中

  • 希望这是有意义的。

    我会在评论中写下这句话,但你知道,在使用了多年之后,我对贡献还是新手。无论如何,您的选项1,即在存在校验和线的条件下,仅具有冗余数据流,这可能是最直接的方法,并且看到您的数据集列受到限制,可能是创建和维护的最快方法。对于这种方法,您可以将其放入Foreach循环容器中,并将其设置为枚举文件。添加用于测试校验和是否存在的变量。添加一个c#脚本任务来测试校验和并填充变量。然后添加2个数据流任务1处理一种格式,第二种处理另一种格式。它将只复制4个组件(文件连接、数据流、源、目标)。然后,对于优先约束编辑器(双击绿色箭头),更改为按表达式计算,并在表达式中选择约束,只需选择变量或!变量(相反),取决于正在馈送的数据流。这是假设您将在不首先将同一数据流任务中的所有2000+文件与联合等组合的情况下进行分段。当然有许多交叉点需要@Shiva answer,但如果您要进行分段表,我认为不需要对联合all进行有条件的拆分

    另一方面,如果您确实不希望数据流任务等出现冗余,则无需在运行SSIS包之前执行powershell脚本。您可以创建一个c#脚本,以便在包中正确执行。例如,我遇到一个问题,即必须导入的数据源中的行尾不一致。因此,在执行数据流任务之前,我有一个c#脚本来规范保存文件的行尾。您可以在ssis包中动态地将文件规范化为一种结构,但正如您所指出的那样,这将需要额外的syste资源,但在文件已加载到内存/处理时,它将是一种结构

    @xpil,15种不同的类型不在原始问题中。我可能会做两件事中的一件。首先实现#2的想法,但要在SSIS脚本中实现。因此,我将通过system.file.io操作除去不需要的行。然后我将构建所有不同的类型,并在脚本中设置一个变量,告诉您它是哪种类型,或者通过不同的DFT失败。或者我实际上只是编写整个操作的脚本,我可能使用也可能不使用SSI,但我只需要使用system.file.io来加载文件检测存在性和类型,然后简单地使用SQLBulkCopy将其放入表中,而不是创建DFT,这将减少安装时的时间消耗。虽然如果文件大到几百MB,您可能仍然希望使用DFT路径。下面是我编写的SSIS脚本任务中的一些片段,它们当然有助于您根据自己的目的进行更改

    如果要修复文件和DFT路由

     string contents = File.ReadAllText(_WFRFullPath);
        contents = Regex.Replace(contents, @"\r\n?|\n", crlf);
        File.WriteAllText(_SSISWorkspaceFullPath, contents);
    
    通过正则表达式读取文件内容修复将文件写回
            SqlConnection sqlConnection = new SqlConnection(sqlConnectionString);
            sqlConnection.Open();
    
            SqlBulkCopy bulkCopy = new SqlBulkCopy(sqlConnection);
            bulkCopy.DestinationTableName = _stagingTableName;
            foreach (DataColumn col in _jobRecDT.Columns)
            {
                //System.Windows.Forms.MessageBox.Show(col.ColumnName);
                bulkCopy.ColumnMappings.Add(col.ColumnName, col.ColumnName);
            }
    
    
            bulkCopy.WriteToServer(_jobRecDT);
    
            sqlConnection.Close();