微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何将XML文件中的Excel序列号转换为SSIS包中的SQL Server的mm / dd / yyyy?

如何解决如何将XML文件中的Excel序列号转换为SSIS包中的SQL Server的mm / dd / yyyy?

我收到了一个XML文件,其中日期字段是Excel序列日期编号,而不是通常的mm / dd / yyyy日期。我无法在以前存在的SSIS包中添加数据转换,因为序列号在XML文件中,而不是Excel文件中。

SSIS包清除一个XML文件并将其加载到sql Server表中。

有人有什么想法吗?我正在使用Visual Studios 2015 fyi。

XML数据段:

    <AGREEMENT_CODE>1960-EMPR</AGREEMENT_CODE>
        <AGREEMENT_NAME>1960-Legacy Employer Conversion 
    Default</AGREEMENT_NAME>
        <AGREEMENT_TYPE>MBA</AGREEMENT_TYPE>
        <FUND_TYPE>Health &amp; Pension</FUND_TYPE>
        <CONTRACT_START_DATE>21916</CONTRACT_START_DATE>
        <EMPLOYER_ID>25568</EMPLOYER_ID>
        <EMPLOYER_NAME>10409</EMPLOYER_NAME>
        <BILLING_ENTITY_CODE>ACT III TELEVISION,L.P.</BILLING_ENTITY_CODE>
        <BILLING_ENTITY_NAME>10409</BILLING_ENTITY_NAME>
        <PARTICIPATION_START_DATE>ACT III TELEVISION,L.P. 
   </PARTICIPATION_START_DATE>
        <PARTICIPATION_SIGNED_DATE>35917</PARTICIPATION_SIGNED_DATE>

Excel序列号位于第6行和第13行。它们是5位数字。

解决方法

Excel中的日期实际上是一个数字,代表(出于所有意图和目的)自1899年12月30日以来的天数。但是下面有一个警告。

因此,您可以使用DATEADD(day,@yourDateNum,'18991230')

将数字转换为日期。

需要说明的是,Microsoft(及其之前的Lotus 1-2-3)在日期计算中存在错误:they assume 1900 is a leap year,但实际上没有。因此,这需要多花一天的时间,因此我已经调整了上面的公式以考虑到这一点。但是结果是,该公式不适用于1900年3月1日之前的日期。

在投入生产之前,请检查具有已知值的公式!

,

我使用了十多年的代码现在来自一个已经不存在的站点

    /// <summary>
    /// Seriously?  For the loss
    /// <see cref="http://www.debugging.com/bug/19252"></see>
    /// </summary>
    /// <param name="excelDate">Number of days since 1900-01-01</param>
    /// <returns>The converted days to date</returns>
    public static DateTime ConvertXlsdtToDateTime(int excelDate)
    {
        DateTime dt = new DateTime(1899,12,31);

        // adjust for 29 Feb 1900 which Excel considers a valid date
        if (excelDate >= 60)
        {
            excelDate--;
        }

        return dt.AddDays(excelDate);
    }

如果要在派生列任务中使用它,则需要将C#转换为SSIS表达式语言。我们将使用三元运算符(boolean) ? truevalue : falsevalue来实现这一点

DATEADD("Day",[CONTRACT_START_DATE] - ([CONTRACT_START_DATE] >= 60 ? 1 : 0),(DT_DATE)"1899-12-30")

通常,我的数据流中将有两个派生列组件,因为这是调试内容的唯一方法。就您而言,我将第一个“派生列”添加1 + Number of Excel列到数据流中。

注意,这里显示的赋值=是您在派生任务的Derived Column NameExpression列中输入的值的简写语法

BaseDate = (DT_DATE)"1899-12-30"
CONTRACT_START_DATE_Offset = [CONTRACT_START_DATE] >= 60 ? -1 : 0
PARTICIPATION_SIGNED_DATE_Offset = [PARTICIPATION_SIGNED_DATE] >= 60 ? -1 : 0

等现在,我可以检查是否正确处理了1900 bug的偏移值。

然后将我的第一个表达式简化为

DATEADD("Day",[CONTRACT_START_DATE] - [CONTRACT_START_DATE_Offset],[BaseDate])

如果您真的要找出可能出问题的地方,我什至会考虑将Col1 - Col1_Offset的数学逻辑封装到前驱衍生列中,以便可以放置数据分接头/数据查看器并捕获值。

作为最低限度的复制,我创建了一个包含OLESRC组件的程序包,该组件将我们的CONTRACT_START_DATE添加到数据流中

SELECT 35 AS CONTRACT_START_DATE
UNION ALL SELECT 21916

使用第一个表达式的“我的派生列”“ OneShot”添加列“ OneShot”

DER Multistatement从第二组表达式中添加BaseDate和CONTRACT_START_DATE_Offset值

DER CSD使用第三个表达式将ContractStartDate添加到数据流中。

enter image description here

在上图中,您可以看到数据查看器的结果(以及此时的元数据副本)。使用DATEADD函数DT_DBTIMESTAMP后,我的数据类型符合预期。

如果您的类型显示为DT_WSTR,请确保您要添加新列,而不是尝试替换现有列。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。