在 SSIS 派生列中替换 NULL

Posted

技术标签:

【中文标题】在 SSIS 派生列中替换 NULL【英文标题】:REPLACE NULL IN SSIS Derived Column 【发布时间】:2018-01-09 17:38:45 【问题描述】:

我有一个将数据从 SAS 传输到 SQL Server 的 SSIS 包。我正在创建一个派生列,但无法使 REPLACENULL 功能工作。我收到错误

“转换规范的字符值无效”

我确信这是因为源中的 NULL 值。这是我当前的派生列表达式:

REPLACENULL(DATEADD("d",(DT_I8)AuthEndDate,(DT_DATE)"1960-01-01"),0)

REPLACENULL 函数在这里不起作用。有什么办法可以做到这一点?我正在使用 SSIS 2008。谢谢。

【问题讨论】:

首先,REPLACENULL() 需要围绕AuthEndDate 的源列(不是整个表达式),但我也很确定您不能将日期转换为 bigint(假设 AuthEndDate实际上是一个日期)。你到底想在这里做什么? 试过了,还是报错。我按原样转换日期的原因是因为数据来自 SAS。当我在没有 NULL 的列上尝试它时,它可以完美地传输。该列的数据类型是 [DT_STR]。 好的,如果 AuthEndDate 实际上是 NULL,你想要下游的什么值? 我希望它只是空白或 0 【参考方案1】:

由于您希望空白/0 向下游流动,因此您需要 if,而不是 replacenull()

请注意,SQL Server 中的空白/0 写入为 1900-01-01,空白/0 不是有效的日期值,因此默认为该值。唯一的其他选项是 NULL。

如果目标是日期时间列,这应该可以工作:

ISNULL(AuthEndDate) ? (DT_DATE)0 : DATEADD("d",(DT_I8)AuthEndDate,(DT_DATE)"1960-01-01")

如果您选择写入 NULL 而不是 1900-01-01,您可以这样做:

ISNULL(AuthEndDate) ? NULL(DT_DATE) : DATEADD("d",(DT_I8)AuthEndDate,(DT_DATE)"1960-01-01")

【讨论】:

【参考方案2】:

您必须使用以下表达式之一:

DATEADD("d",(DT_I8)REPLACENULL([AuthEndDate],0),(DT_DATE)"1960-01-01")

ISNULL([AuthEndDate]) ? (DT_DATE)"1960-01-01" : DATEADD("d",(DT_I8)AuthEndDate,(DT_DATE)"1960-01-01")

请注意,您不能使用可以返回多种数据类型的逻辑,两种情况都必须返回数据类型 (DT_DATE)

【讨论】:

【参考方案3】:

如果源返回 NULL,则在 AuthEndDate 而不是在计算之后尝试 REPLACENULL。您拥有的语句将尝试使用 NULL 进行计算,这永远不会是好的。

所以...

REPLACENULL(DATEADD("d",REPLACENULL((DT_I8)AuthEndDate,0),(DT_DATE)"1960-01-01"),0)

编辑 - 替换 null 然后应用转换:

DATEADD("d",(DT_I8)REPLACENULL(AuthEndDate,0),(DT_DATE)"1960-01-01")

您将不再需要第一个 REPLACENULL,因为我们现在在计算之前处理它。

因此:

DATEADD("d",REPLACENULL((DT_I8)AuthEndDate,0),(DT_DATE)"1960-01-01")

编辑:您可以将 0 更改为您希望 NULL 变为的任何内容,0 是占位符。

【讨论】:

嗨,我试过了,但仍然收到同样的错误。 请看我的编辑,尝试做replacenull然后转换。我们应该首先完成 replacenull,这是我的错。

以上是关于在 SSIS 派生列中替换 NULL的主要内容,如果未能解决你的问题,请参考以下文章

SSIS派生列问题

使用 SSIS 从列中删除特殊字符 " 和 '

SQL SSIS派生列公式/语法问题

SQL SSIS 使用派生列转换来处理空数据.. 替代方案?

在 SSIS 派生列中将字符串转换为日期

使用 SSIS 派生列提取日期值