[英]How do I insert Excel date format (mm/dd/yyyy) into SQL Server format (yyyy-mm-dd)?
[英]How do I convert Excel Serial Date Numbers in an XML file to mm/dd/yyyy for SQL Server in an SSIS Package?
我收到了一個 XML 文件,其中日期字段是 Excel 序列日期編號,而不是通常的 mm/dd/yyyy 日期。 我在向我先前存在的 SSIS package 添加數據轉換時遇到問題,因為序列號在 XML 文件中,而不是 excel 文件中。
SSIS package 清理並加載一個 883812976388 文件到 SQL 服務器表中。
有人有什么想法嗎? 我在 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 & 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)在日期計算中存在錯誤: 他們假設 1900 年是閏年,但事實並非如此。 因此,還有額外的一天,我已經調整了上面的公式以考慮到這一點。 然而,結果是此公式不適用於 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
(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 Name
和Expression
列的值的簡寫語法
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 錯誤的偏移值。
然后將我的第一個表達式簡化為
DATEADD("Day", [CONTRACT_START_DATE] - [CONTRACT_START_DATE_Offset], [BaseDate])
如果您真的想找出 go 可能出錯的地方,我什至會考慮將Col1 - Col1_Offset
中的數學邏輯封裝到前體派生列中,這樣我就可以在其上放置數據抽頭/數據查看器並捕獲值.
作為最小復制,我創建了一個 package,它有一個 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 添加到數據流中。
在上圖中,您可以看到數據查看器的結果(以及此時的元數據副本)。 使用 DATEADD function - DT_DBTIMESTAMP 后,我的數據類型符合預期。
如果您的類型顯示為 DT_WSTR,請確保您正在添加新列而不是嘗試替換現有列。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.