【问题标题】:SSIS Import a date and time from a txt to a table datetimeSSIS 将日期和时间从 txt 导入表 datetime
【发布时间】:2015-04-13 06:16:23
【问题描述】:

所以我想从 txt 中导入日期时间:

2015-01-22 09:19:59

使用数据流进入表。我的平面源文件和目标数据库设置得很好。我将高级设置中该列的 txt 输入的数据类型和输入输出属性更改为:

数据库时间戳 [DT_DBTIMESTAMP]

这与用于表的数据库的数据类型相同,因此应该可以工作。

但是,当我执行包时,我收到一条错误消息,提示数据转换失败...我该如何实现?

[Import txt data [1743]] Error: Data conversion failed. The data conversion for column "statdate" returned status value 2 and status text "The value could not be converted because of a potential loss of data.".

[Import txt data [1743]] Error: SSIS Error Code DTS_E_INDUCEDTRANSFORMFAILUREONERROR.  The "output column "statdate" (2098)" failed because error code 0xC0209084 occurred, and the error row disposition on "output column "statdate" (2098)" specifies failure on error. An error occurred on the specified object of the specified component.  There may be error messages posted before this with more information about the failure.

[Import txt data [1743]] Error: An error occurred while processing file "C:\Program Files\Microsoft SQL Server\MON_Datamart\Sourcefiles\tbl_L30T1.txt" on data row 14939.

在他给出错误的那一行,日期时间被空格填满。这就是为什么在表格上检查了“允许空值”但我的 SSIS 包由于某种原因给出了错误...我可以在某个地方告诉包也允许空值吗?

【问题讨论】:

  • 时间戳日期时间
  • 什么意思?它在表本身的数据类型上显示“日期时间”当我检查 OLE DB 目标中的映射时,目标列显示数据库时间戳。这在 DTS 包中工作(我正在转换)-> timestamp = datetime
  • 在 SQL Server 中,我们有数据类型 datetimetimestamp (msdn.microsoft.com/en-us/library/ms187752.aspx)。抱歉,我没有意识到在 SSIS 中 DT_DBTIMESTAMP 映射到 datetime,因为命名约定与 T-SQL 不一致。
  • 是的,我理解得很好,因为它在 OLE DB 目标的目标列中清楚地表示“数据库时间戳”。您对我的问题可能是什么以及如何解决有什么建议吗?也许数据转换很好,但是由于 txt 文件中某些行上的空格而出现了该错误?我可以将它设置为在任何地方接受特定列中的空值,以防止它在空行上抛出错误吗?
  • 您能否将 CSV 的值临时转储到 varchar 字段中,以便查询数据?您可能有类似2015-02-00...(即无效日期)或2015-02-12 14:37:39.123456(即精度高于数据类型允许...或类似的日期)的日期

标签: sql-server-2008 datetime ssis type-conversion data-conversion


【解决方案1】:

我建议你将数据导入到一个字符字段中,然后在输入后进行解析。

以下功能应该可以帮助您:

SELECT IsDate('2015-01-22 09:19:59')
     , IsDate(Current_Timestamp)
     , IsDate('          ')
     , IsDate('')

IsDate() 函数在它认为该值是日期时返回 1,而在不是时返回 0。 p>

这将允许您执行以下操作:

SELECT value_as_string
     , CASE WHEN IsDate(value_as_string) = 1 THEN
         Cast(date_as_string As datetime)
       ELSE
         NULL
       END As value_as_datetime
FROM   ...

【讨论】:

【解决方案2】:

我自己解决了。感谢您的建议 gvee,但我这样做的方式更容易。

在平面文件源中,当在高级选项卡中建立新连接时,我根据数据库中的表修复了所有数据类型,除了带有时间戳的列(在我的例子中,它被称为“statdate”)!我将此数据类型更改为 STRING 因为否则即使在任何脚本能够执行之前,我的平面文件源也会给我一个转换错误,而解决此问题的唯一方法是将错误输出设置为忽略我不想要的失败。 (在高级设置中将数据类型设置为字符串后,您仍然必须更改数据类型,方法是右键单击平面文件源 -> 显示高级编辑器 -> 转到输出列并将数据类型从日期更改为字符串。 )

在将时间戳设置为字符串后,我添加了一个带有此表达式的派生列以删除所有空格并将其赋予“NULL”值:

TRIM(<YourColumnName>) == "" ? (DT_STR,4,1252)NULL(DT_STR,4,1252) : <YourColumnName>

接下来我添加了一个数据转换来将字符串设置回时间戳。数据转换最终连接到 OLE DB 目标。

我希望这对以后遇到同样问题的人有所帮助。

最终结果:Picture of data flow

【讨论】:

  • 干得好。您还可以直接在上面的表达式中转换为日期时间数据类型,并为自己节省一个额外的步骤。
  • 这正是我在评论中所建议的。很高兴你想出来了。 :) 但我认为您可以简单地将派生列转换为时间戳,然后您就不需要额外的数据转换步骤。
  • 我应该在表达式末尾添加什么来跳过单独的数据转换步骤? @Nick.McDermaid
  • 将整个表达式转换为日期时间,并将派生列的数据类型设置为 DT_DBTIMESTAMP。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-09
相关资源
最近更新 更多