【问题标题】:Import Fixedwidth file using SSIS使用 SSIS 导入 Fixedwidth 文件
【发布时间】:2021-08-23 07:12:59
【问题描述】:

我有一个固定宽度的文件,没有标题和大约 900 列的大量列。 有没有一种像在 SSIS 中一样创建源元数据的简单方法,或者我需要逐一创建列,或者使用非常手动且耗时的方法。

样本数据:

AXC98976GHHL66678787656UKAPPLE+44POS

非常感谢您的帮助。

【问题讨论】:

  • 您有元数据明细吗?比如起始位置、长度、数据类型、名称?
  • 是的,我有元数据并且我已经使用它创建了我的目标表,我需要帮助创建源组件,因为文件包含 900 个没有标题的列。

标签: file import ssis fixed-width


【解决方案1】:

这是一个实验,因为我以前从未尝试过,但是如果您可以将元数据存储在表中。您可以将元数据加载到数据表中并用它处理每一行。我已经模拟了一些示例代码:

    static void Main(string[] args)
    {
        // Simulate var lines = System.IO.File.ReadAllLines("[path]");
        List<string> lines = new List<string>();
        lines.Add("AXC98976GHHL66678787656UKAPPLE+44POS");

        var metadata = getMetaData();

        string sql = string.Format(
                @"insert into [your table]
                    values(?,{0})"
                        , new System.Text.StringBuilder().Insert(0, ",?", metadata.Rows.Count - 1).ToString());

        foreach (string line in lines)
        {
            using (var conn = new OleDbConnection(cstr))
            {
                using (var cmd = new OleDbCommand(sql, conn))
                {
                    cmd.CommandType = CommandType.Text;
                    foreach (DataRow row in metadata.Rows)
                    {
                        switch (row["DataType"].ToString())
                        {
                            case "string":
                                cmd.Parameters.Add(string.Format("param{0}", row["StartingPosition"]), OleDbType.VarChar, (int)row["Length"]).Value = line.Substring((int)row["StartPosition"], (int)row["Length"]);
                                break;
                            case "int":
                                cmd.Parameters.Add(string.Format("param{0}", row["StartingPosition"]), OleDbType.Integer).Value = int.Parse(line.Substring((int)row["StartPosition"], (int)row["Length"]));
                                break;
                            //Add more for each data type
                        }

                    }
                    
                    conn.Open();
                    cmd.ExecuteNonQuery();
                }

            }
        }
    }

    public static DataTable getMetaData()
    {
        DataTable dt = new DataTable();
        using (var conn = new OleDbConnection(cstr))
        {
            string sql = "select FieldName, DataType, StartPosition, Length from metatdataTable";
            using (var cmd = new OleDbCommand(sql, conn))
            {
                cmd.CommandType = CommandType.Text;
                conn.Open();
                dt.Load(cmd.ExecuteReader());
            }
        }
        return dt;
    }

【讨论】:

  • 感谢 Keith,如果我能通过低代码方法获得相同的结果,我会尝试并感谢,因为我主要希望加快源组件中的字段创建,因为目前不支持在 SSIS 中导入列元数据。
  • 这就是为什么我给你一个脚本任务来处理你的元数据表。
【解决方案2】:

生成连接管理器的两个选项可能是:

修改 SSIS 包中的 XML

  1. 在项目中创建平面文件连接管理器
  2. 使用 TextTemplates 甚至 excel 为每一列生成 xml
  3. 将其粘贴到 ssis xml(F7 - 项目的 xml 视图)

xml 看起来像这样:

<DTS:ConnectionManager
          DTS:Format="FixedWidth"
          DTS:LocaleID="1033"
          DTS:HeaderRowDelimiter="_x000D__x000A_"
          DTS:RowDelimiter=""
          DTS:TextQualifier="_x003C_none_x003E_"
          DTS:CodePage="1252"
          DTS:ConnectionString="C:\MyFilePath\FixedWidth.txt">
          <DTS:FlatFileColumns>
            <DTS:FlatFileColumn
              DTS:ColumnDelimiter=""
              DTS:ColumnWidth="10"
              DTS:MaximumWidth="10"
              DTS:DataType="129"
              DTS:ObjectName="Column Name"
              DTS:DTSID="{2448DB1E-03F9-4AFC-9B8F-75C71AF3F99B}" --> some guid
              DTS:CreationName="" />
            <DTS:FlatFileColumn
              DTS:ColumnDelimiter=""
              DTS:ColumnWidth="5"
              DTS:MaximumWidth="5"
              DTS:DataType="129"
              DTS:ObjectName="Column Name 2"
              DTS:DTSID="{40B08811-64B1-4B7F-8FA8-48ACA21DCD8E}"
              DTS:CreationName="" />
           </DTS:FlatFileColumns>
        </DTS:ConnectionManager>

使用 BIML Express

1- 添加平面文件管理器

2- 编写一个循环来添加列

对于如何编写循环、使用文件作为源、使用 .net 列表内联执行等,有很多选项。这大致是 biml 生成 ssis 包的样子——一次你有连接管理器,你可以手动修改包或使用 BIML 来完成整个事情:

<Biml xmlns="http://schemas.varigence.com/biml.xsd">
    <Connections>
        <FlatFileConnection Name="Flat File Connection Manager" FilePath="C:\MyFilePath\FixedWidth.txt" FileFormat="Flat File Connection Manager" />
    </Connections>
    <Packages>
        <Package Name="Package" Language="None" ProtectionLevel="EncryptSensitiveWithUserKey">
            <Variables>
                <Variable Name="RowType" DataType="String" IncludeInDebugDump="Exclude">Before</Variable>
            </Variables>
        </Package>
    </Packages>
    <FileFormats>
        <FlatFileFormat Name="Flat File Connection Manager" CodePage="1252" TextQualifier="_x003C_none_x003E_" FlatFileType="FixedWidth" RowDelimiter="">
            <Columns>
                <#some foreach loop starts here#>
            <Column Name="Column 0" Length="10" DataType="AnsiString" Delimiter="" TextQualified="false" ColumnType="FixedWidth" MaximumWidth="10" />
            <Column Name="Column 1" Length="5" DataType="AnsiString" Delimiter="" TextQualified="false" ColumnType="FixedWidth" MaximumWidth="5" />
            <Column Name="Column 2" Length="6" DataType="AnsiString" Delimiter="" TextQualified="false" ColumnType="FixedWidth" MaximumWidth="6" />
            <#}#>
            </Columns>
        </FlatFileFormat>
    </FileFormats>
</Biml>

【讨论】:

  • 第一种方法看起来很适合我的目的,因为我可以使用 SQL 代码为所有列生成所需的 xml 脚本,因为已经使用文件提供的元数据创建了目标表。
猜你喜欢
  • 2015-08-25
  • 2023-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多