網路上有看到有人有一樣的問題,Decimal Formatting from OLEDB Source to Flat File ,但沒有明確的解答,於是我做了一下測試,發現一些奇怪的事,在資料庫引擎端,NUMERIC的功能幾乎等於於DECIMAL,但在Intergration Services,DT_NUMERIC與DT_DECIMAL兩個差異倒是滿大的喔
首先我產生幾筆測試資料,這測試資料是我參考別人所建的,如下圖(一),資料表有三個欄位,欄位Num_decimal的格式為DECIMAL(10,6),Num_numeric的為NUMERIC(10,6),另一個欄位為說明
圖(一)
IS封裝的資料流程如下圖(二),兩個衍生資料行分別處理Num_decimal與Num_numeric欄位,之後發現在輸出結果一樣後,有做調整,這待會再看
圖(二)
左邊的衍生資料行內容如下圖(三),針對Num_decimal欄位作資料型態轉換,轉成貨幣[DT_CY]、數值[DT_NUMERIC]、十進位[DT_DECIMAL]、字串[DT_STR]及Unicode字串[DT_WSTR],右邊的衍生資料行內容幾乎一樣,差別只是針對的是Num_numeric欄位囉,就不另外截圖了
圖(三)
轉換過程中,我用資料檢視器觀看緩衝區的資料當來源來說,然後跟最後的產出文字檔結果作對比,如下圖(四),在這個階段,兩個衍生資料行的測試結果都一樣,所以我只截其中一畫面表達- Num_decimal欄位 --> Num_decimal欄位 來源格式為[NUMERIC],目的地格式為數值 [DT_NUMERIC] 0.多的0不見了,小數位數都一樣(Num_numeric欄位轉換結果相同,這應可說明在資料庫引擎端NUMERIC還是DECIMAL是沒差別的)
- DT_CY欄位 --> DT_CY欄位 來源目的地格式皆為貨幣 [DT_CY] 0.多的0有保留,但會去掉小數位皆為0的
- DT_NUMERIC(10,6)欄位 --> DT_NUMERIC(10,6)欄位 來源目的地格式皆為數值 [DT_NUMERIC] 與第一項的結果同
- DT_DECIMAL(6)欄位 --> DT_DECIMAL(6)欄位 來源目的地格式皆為十進位 [DT_DECIMAL] 0.多的0有保留,但小數點以下皆為0又去掉了(這與第三項DT_NUMERIC結果相反,這應可說明在IS端差很大)
- DT_STR(11)欄位 --> DT_STR(11)欄位 來源目的地格式皆為字串 [DT_STR] 雖在緩衝區時,0.多的0已經去掉了,但忠實還原結果到文字檔,來源目的結果一樣
- DT_WSTR(11)欄位 --> DT_WSTR(11)欄位 來源目的地格式皆為Unicode 字串 [DT_WSTR] 與第五項同
圖(四)
從圖(四)的幾個結果比較下來,字串轉字串的結果(第五項第六項)比較像是我們需要的,但在緩衝區中有小數點的這種值,在數值轉文字的過程中會去掉0.多的0,那第四項轉DT_DECIMAL的,似乎不會去掉0,但會去掉小數點之後皆為0的,那我把兩種結合呢?先轉成DT_DECIMAL再轉成DT_STR看看,試試囉,如下圖(五)
圖(五)
結果比較如下圖(六 ),這樣結果跟第四項又一樣了,看來還是不行
這樣奇怪的現象我在SSIS 2008 R2試的結果也一樣,這應該算bug吧!那到底要如何保留開頭的0及保留有效的小數位數呢?
- How to Import Negative Decimal or Floating Values to Flat File Without Losing Leading Zero,此篇提供一種解法,得用到IS的Expression
- 第二種方法較簡單,既然在資料流程中資料轉換會出問題,那我就在資料庫引擎這端就先將數值轉成字串就好了啦,像我這個例子,
select Num_decimal,Num_numeric,cComment from test改成
select cast(Num_decimal as varchar(11)) Num_decimal,cast(Num_numeric as varchar(11)) Num_numeric,cComment from test
就搞定啦
0 意見:
張貼留言