【问题标题】:Retain NULL not working for all columns保留 NULL 不适用于所有列
【发布时间】:2017-05-18 20:47:08
【问题描述】:

我有一个包含以下信息的平面文件,我正在尝试将其加载到具有与日期相同的列和数据类型的 SQL Server 表中 -

StartDate,EndDate
2017-01-02,2017-03-01

2017-01-02,2017-03-01

请注意,第二行是空白的。现在我将两个源列都设置为DT_DBDATE 数据类型。同样在平面文件源中,我正在检查选项Retain null values from the source as null values in the data flow

在目标 DFT,我启用了 Keep NULL 选项。 这是问题所在。当我运行包时,我看到 StartDate 为空,但对于 EndDate,我看到以下错误 -

错误:年、月和日参数描述了无法表示的日期时间。

知道如何克服这个问题或导致这个问题的原因吗?

【问题讨论】:

  • 平面文件中的日期是一个巨大的痛苦。我建议将中间表作为文本暂存,然后在插入真实表时重新格式化。可能会为您省去麻烦。没有显示问题的原因,但至少你有一个快速的解决方法。
  • 它需要两个字段,但它将空白行作为一个字段读取(因为没有逗号),所以 EndDate 甚至没有 NULL,它只是丢失了。
  • @Donnie - 感谢您指出这一点,您是对的,该行没有所需的分隔符。让我尝试使用分隔符。

标签: sql-server ssis etl ssis-2012


【解决方案1】:

问题

空行不包含任何列分隔符,这意味着它只包含一列,这会在读取 falt 文件时出现问题。

如何解决

在平面文件连接管理器中删除列分隔符并将每一行读取为DT_STR 类型的一列并将长度设置为4000

然后添加一个脚本组件并执行以下操作:

  1. 检查该行是否为空
    • 如果是,则输出空列
    • 如果不将行拆分为列
  2. 输出必须包含您需要的列

你可以使用类似的代码:(我用vb.net)

    Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)

        If Not Row.Column0_IsNull AndAlso
                    Not String.IsNullOrEmpty(Row.Column0) Then

            Dim strcolumnms() As String = Row.Column0.Split(CChar(";"))

            Dim dtTemp As Date


            If DateTime.TryParse(strcolumnms(0), System.Globalization.CultureInfo.InvariantCulture, Globalization.DateTimeStyles.None, dtTemp) Then

                Row.Column1 = dtTemp

            Else

                Row.Column1_IsNull = True

            End If


            If DateTime.TryParse(strcolumnms(1), System.Globalization.CultureInfo.InvariantCulture, Globalization.DateTimeStyles.None, dtTemp) Then

                Row.Column2 = dtTemp

            Else

                Row.Column2_IsNull = True

            End If


        Else

            Row.Column1_IsNull = True
            Row.Column2_IsNull = True





        End If

    End Sub

处理平面文件中的日期

在处理存储在平面文件中的日期值(或其他数据类型)并使用Script ComponentData Conversion 转换它们(在检查它们是否格式正确之后)时,最好选择DT_STR 类型.

使用脚本组件

首先你必须添加一个Script component,将日期列标记为输入,创建一个DT_DBDATE类型的新输出列

如果您想检查特定日期格式,您可以使用DateTime.TryParseExact() 方法或使用DateTime.TryParse() 尝试根据 CultureInfo 日期格式解析日期。

我举两个例子: 假设输入列名为inDate,输出列为outDate

DateTime.TryParseExact()

Dim strFormats() As String = {"yyyy-MM-dd"}

Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)



    If Not Row.inDate_IsNull AndAlso
                 Not String.IsNullOrEmpty(Row.inDate) Then


        Dim dtTemp As DateTime

        If DateTime.TryParseExact(Row.inDate, strFormats, System.Globalization.CultureInfo.InvariantCulture, Globalization.DateTimeStyles.None, dtTemp) Then

            Row.outDate = dtTemp

        Else

            Row.outDate_IsNull = True

        End If



    End If
End Sub

DateTime.TryParse()

 Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)



    If Not Row.inDate_IsNull AndAlso
                 Not String.IsNullOrEmpty(Row.inDate) Then


        Dim dtTemp As DateTime

        If DateTime.TryParse(Row.inDate, System.Globalization.CultureInfo.InvariantCulture, Globalization.DateTimeStyles.None, dtTemp) Then

            Row.outDate = dtTemp

        Else

            Row.outDate_IsNull = True

        End If



    End If
End Sub

您可以在这篇文章中阅读有关使用 SSIS 脚本组件进行日期时间转换的更多信息:

使用数据转换转换

使用数据转换组件将DT_STR 列转换为DT_DBDATE,并在Error Output 上设置Ignore failure,以便将无法转换的值替换为NULL

【讨论】:

  • 感谢您的更新,我完全同意在平面文件中处理日期非常烦人。最好通过数据转换或派生列检查空白,这是我所做的,我在这里写了博客 - vankadarakarthik.com。 Donnie 指出了一个非常相关的点,即没有分隔符本身。我会跑一次看看是否有帮助
  • 感谢您的努力和更新的答案。欣赏它。
猜你喜欢
  • 2018-03-04
  • 1970-01-01
  • 2022-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-17
  • 2023-03-20
  • 1970-01-01
相关资源
最近更新 更多