【问题标题】:Need to import a DATE column in excel to a SQL table using SSIS需要使用 SSIS 将 Excel 中的 DATE 列导入 SQL 表
【发布时间】:2018-08-22 09:55:13
【问题描述】:

我正在使用 Microsoft Visual Studio 2010 Professional集成服务。对于数据库的管理,我使用 Microsoft SQL SERVER Management Studio 2012

我有一个包含几张工作表的 excel 文件。在某些工作表中,有一列 DATE。 我需要将这些值导入 SQL 表。

我遇到的问题是 OLE DB 源不断将几个 excel 列 CALLED 'date' 设置为 DT_WSTR,长度为 255,而不是 DATE 数据类型。我尝试将其更改为 DATE 作为外部列中 EXCEL 源输出下的数据类型,然后在日期列中...但它始终将 excel 列设置为 DT_WTSR 并具有 255(长度)...

您可以在下面看到我正在使用的日期列的数据。

**DATE** 

06/jun/16
13/oct/15
n/a
07/jun/16
20/may/13
n/a
n/a
n/a
n/a
n/a
17 Apr 2018

我在 SQL 表中得到了什么:

**DATE**
42527
42290
n/a
42528
41414
n/a
n/a
n/a
n/a
n/a
17 Apr 2018

想要什么?

**DATE**
    06/06/2016
    10/13/2015
    n/a
    06/07/2016
    05/20/2013
    n/a
    n/a
    n/a
    n/a
    n/a
    04/17/2018

TYPEGUESSROWS(使用 regedit)中设置为 8(十六进制)。我已经尝试将其更改为 0,甚至我给了它一个很长的数字,但它不起作用。

我还更改了连接字符串,为 IMEX=? 添加了几个假设(我尝试过 1、2 和 3 where is ?)但无济于事。如您所见,日期列中有混合数据类型......我需要保留这些值,因为它出现在 LAST 示例中。如果我将更多带日期的行移到第一行,它可以工作,但我们根本无法更改 excel 文件。那么我们如何才能保持我展示的最后一个表格中的值呢?谢谢!

重要:n/a 值比日期多得多...这意味着即使我使用很长的 TYPEGUESSROWS SSIS 也会使用文本... :( 它必须是一种获取方式我想要的桌子!

【问题讨论】:

  • n/a 不是日期,其他日期格式不一致,因此选择了相应的数据类型。这里常用的方法是加载到一个暂存表(其中包含所有 varchar 字段),然后使用 T-SQL 清理它并合并到目标表中。
  • 您是说我们需要使用 T-SQL 将 42527 转换为正确的日期 06/06/2016?我正在使用临时表,是的。暂存表的负载显示此值:42527 而不是 06/06/2016。所以我需要获取这些值并使用 T-SQL 进行转换,然后将其移动到新表(转换后的值)。
  • 是的。 Excel 数据类型不够可靠,显然 Excel 表中的实际数据不够可靠。您需要对至少三种情况执行清理过程:1. N/A 2. 数字(加到 1/1/1900 并取 1) 3. 看起来像日期的字符串(使用 TRY_CAST)

标签: ssis ssis-2008


【解决方案1】:

从 excel 导入时,您可以使用访问模式作为 SQL 命令并将查询编写为“SELECT cdate(date) FROM [SHEET1$] where date'n/a'” 在这里,您可以将“日期”更改为“日期列名称”,将“Sheet1”更改为您的 sheetName。 然后检查预览数据以日期格式显示。

如果还有什么问题请告诉我

谢谢

萨西

【讨论】:

  • where 子句将限制数据集。将案例工作.... case when [col] ='n/a' then null else cdate(date) end ???
【解决方案2】:

Excel 是一个不可靠的数据源。

首先没有验证。任何人都可以在任何地方输入任何内容

其次,excel驱动在数据类型方面不一致。

我建议您导入一个全 varchar(或 nvarchar)暂存表,然后使用 T-SQL 清理它。

这是一个例子:

DECLARE @StagingTable TABLE (ThisIsADate NVARCHAR(100))

INSERT INTO @StagingTable (ThisIsADate)
VALUES
('42527'),
('42290'),
('n/a'),
('42528'),
('41414'),
('n/a'),
('n/a'),
('17 Apr 2018')


SELECT 
CASE 
WHEN ThisIsADate = 'n/a' 
THEN NULL
WHEN TRY_CONVERT(INT,ThisIsADate) IS NOT NULL 
THEN CONVERT(DATETIME,DATEADD(d,CONVERT(INT,ThisIsADate)-1,'1900-01-01'))
ELSE TRY_CONVERT(DATETIME,ThisIsADate,113)
END Converted,
ThisIsADate
FROM @StagingTable

此示例尝试清理您在一个内联语句中确定的案例。这变得非常复杂并且容易出错。更好的方法是将目标转换字段放在临时表中并迭代地执行:

DECLARE @StagingTable TABLE (
    ThisIsADate NVARCHAR(100), ConvertedDate DATETIME);

INSERT INTO @StagingTable (ThisIsADate)
VALUES
('42527'),
('42290'),
('n/a'),
('42528'),
('41414'),
('n/a'),
('n/a'),
('17 Apr 2018');


UPDATE @StagingTable
SET ConvertedDate = CONVERT(DATETIME,DATEADD(d,CONVERT(INT,ThisIsADate)-1,'1900-01-01'))
WHERE TRY_CONVERT(INT,ThisIsADate) IS NOT NULL;

UPDATE @StagingTable
SET ConvertedDate = TRY_CONVERT(DATETIME,ThisIsADate,113)
WHERE TRY_CONVERT(DATE,ThisIsADate,113) IS NOT NULL;


SELECT * FROM @StagingTable;

看起来很复杂,但它是一种非常可靠的导入和清理 excel 数据的方法。不要走上摆弄 IMEX 和所有这些 excel 驱动程序设置的道路。即使您找到了一个有效的组合并且可以部署到生产环境中,它也没有解决最终用户可以在这些字段中输入任何内容的事实。

【讨论】:

  • 是的,在我的临时表中,几乎所有列都有 nvarchar 数据类型(至少是必要的,除了 creationdate 和 lastchangedate)。我尝试使用: UPDATE @stagingtable SET convertDate=convert(datetime, CONVERT(float,convertedDate)) WHERE len(covertedDate)=5 and isnumeric(convertedDate)=1 结果为 42451 as March 24 2016 12:00 AM 其中我不想...对于 n/a,可以保留为 n/a - 我们以这种方式使用它。我只需要将这些数值转换为正确的日期,例如 12-20-2017 :)
  • 您的 UPDATE @StagingTable SET ConvertedDate = CONVERT(DATE,DATEADD(d,CONVERT(INT,ThisIsADate)-1,'1900-01-01')) TRY_CONVERT(INT,ThisIsADate) 不是空值;诀窍 :D 一个小细节:它只给出了一天,我们怎么能把时间变成 00:00:00 ,我只需要这个......也许使用连接?好吧,我使用了 concat(your expression, ' 00:00:00') 并且它有效。谢谢。对我来说,以这种方式将 NUMERIC 值清除为日期的 DATE 数据类型就足够了。 :) 一切都很好。谢谢!
  • 更好的方法是转换为 DATETIME 而不是 DATE。我将更改代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-29
  • 1970-01-01
  • 1970-01-01
  • 2016-11-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多