保留NULL不适用于所有列

时间:2017-05-18 20:47:09

标签: sql-server ssis etl ssis-2012

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

DT_DBDATE

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

在目的地DFT,我启用了public interface Field<T> { ... // The resulting Condition will never be null @Nonnull // The argument Field can be null for convenience Condition eq(@Nullable Field<T> other); } 选项。 这是问题所在。当我运行包时,我看到StartDate为null,但对于EndDate,我看到以下错误 -

  

错误:年,月和日参数描述了无法表示的DateTime。

任何想法如何克服这个或导致这个问题的原因?

DataViewer output

1 个答案:

答案 0 :(得分:1)

问题

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

如何修复

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

enter image description here

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

  1. 检查行是否为空
    • 如果是,则输出空列
    • 如果没有将行拆分为列
  2. 输出必须包含您需要的列
  3. enter image description here

    您可以使用类似的代码:(我使用的是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
    

    处理Flat文件中的日期

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

    使用脚本组件

    首先,您必须添加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_DBDATEError OutputIgnore failure,以便将无法转换的值替换为{{1} }

    enter image description here