SSIS 如何處理邏輯類型的轉換?


邏輯類型是最常用的數據類型之一,一般編程語言,例如,C#、Java和R等都支持布爾類型,用於表示邏輯真(true)和假(false),然而,SQL Server沒有純的布爾類型,但是,在編程時,可以使用bit 類型來代替邏輯類型,bit類型只有兩個有效值:0 和 1。在設計數據表架構時,使用0代表邏輯假,使用1代表邏輯真。當SQL Server的數據表作為外部數據源時,SSIS引擎需要把數據加載到緩存,由於SSIS引擎內置布爾類型,它會自動把bit 類型轉換成布爾類型,把 1 轉換成 True,把0 轉換成False,轉換的流程時透明的。

在SQL Server的語法中,bit類型的0和1,跟整數類型的0和1是不同的:

  • 當把整數類型轉換為bit類型時,SQL Server把整數0轉換為bit類型的0,把非整數0轉換為bit類型的1。
  • 當把bit類型轉換為整數類型時,SQL Server把bit類型的0轉換為整數0,bit類型的1轉換為整數類型的1。

但是,當SSIS引擎把布爾類型轉換為整數類型輸出到SQL Server時,轉換的流程是:

  • SSIS引擎把False轉換為整數0,True會轉換為整數-1

一,邏輯類型的轉換

SSIS引擎會自動轉換外部數據源的類型,把外部數據源的類型轉換為SSIS支持的數據類型。SSIS內置的原生數據類型的命名格式是DT_xxxx,關於SSIS數據類型的詳細信息,請查閱:SSIS 數據類型和類型轉換

如果外部數據源是SQL Server,列的數據類型是bit,那么Package在加載數據時自動進行類型轉化,把bit類型轉換為DT_BOOL類型,轉換的過程是把 1 轉換成 True,把0 轉換成False。在輸出數據時,把DT_BOOL類型轉換為外部數據源支持的邏輯類型,如果外部數據源是bit類型,那么轉換的過程是把True轉換為1,把0轉換為False,轉換過程是透明的。

由於bit類型和DT_BOOL是兼容的,所以轉換之后,數據仍然是等價的,但是,如果要把SSIS的DT_BOOL類型轉換成外部數據源的Int 類型(0,1),或轉換成 String 類型(“0” 或 “1”),而不是(“True”或“False”),直接轉換是有風險的,轉換的過程可能是不等價的。這就需要增加一個派生列,使用SSIS的表達式,通過顯式類型轉換來實現,例如:

IsFlagged_bit = [IsFlagged] ? (DT_UI1)1 : (DT_UI1)0

二,探究bit類型和整數類型的轉換

使用以下腳本創建測試數據,表TestBit中有一列IsMerged是bit類型,插入兩行數據,IsMerged的值分別是0和1:

create table dbo.TestBit
(
ID int,
name varchar(10),
IsMerged bit
)

insert into dbo.TestBit
values(1,'a',0),(2,'b',1)

1,在Package中檢查bit類型

在Package中創建數據流任務,使用OLE DB Source 來獲取TestBit的數據,設置OLE DB源的連接管理器:

點擊按鈕“Preview...”,看到IsMerged 字段的值不是0 或1, 而是被SSIS轉換成True 或False:

2,把bit類型的數據插入到整數類型中

SQL Server中的整數類型是指smallint、int和bigint,使用OLE DB Destination,把bit 類型的數據直接插入到目標表整數列中,例如,把dbo.TestBit的數據插入到表dbo.TestBit_Target中。

create table dbo.TestBit_Target
(
ID int,
name varchar(10),
IsMerged smallint
)
go

創建映射關系如下圖所示,輸入列IsMerged是DT_BOOL類型,目標列IsMerged是DT_I2類型:

從映射關系中,可以看出,轉換實際上發生在類型DT_BOOL和 類型DT_I2之間,即是SSIS支持的原生類型之間的相互轉換,雖然DT_BOOL和 DT_I2之間的轉換是合法的,SSIS引擎不會拋出任何異常,但是轉換的結果是不等價的。

3,查看插入的結果

從SQL Server數據庫中查看插入的結果,當把外部數據源的Bit類型的數據轉換為smallint時,SSIS 把0(bit)轉變成 0(smallint),卻把1(bit)轉換成 -1(smallint),這是一個錯誤,但是SSIS不會拋出任何異常消息:

4,故障排除

產生錯誤的根本原因是SSIS引擎無法直接把類型DT_BOOL直接轉換為類型DT_I2,為了排除這種錯誤,用戶可以使用派生列,通過SSIS表達式顯式轉換數據類型:

(DT_I2)(IsMerged ? 1 : 0)

三,類型轉換的流程

SSIS引擎對數據類型的處理流程是:

  • 對於外部數據組件,不管是用作輸入的數據源組件,還是用作輸出的數據目的組件,SSIS都會把外部數據組件的數據類型等價轉換為SSIS支持的原生數據類型,類型以DT_xxxx命名;
  • 映射關系發生在SSIS支持的原生數據類型之間,因此,數據轉換是指 DT_type和DT_type之間的類型轉換;

SSIS引擎和外部數據源的類型轉換,雖然會有精度的損失,例如,時間,但是,可以視為是等價的,轉換的流程是:

  • 在加載數據時,SSIS把外部數據源的數據加載到緩存中,把外部數據源的類型轉換為SSIS支持的數據類型;
  • 在輸出數據時,SSIS把緩存的數據輸出到外部的目標容器中,把SSIS的數據類型轉換為外部數據支持的數據類型;

在數據類型的轉換過程中,開發人員需要明確知道類型轉換的結果,即使SSIS引擎不拋出任何異常,也要復查Package輸出的結果,避免出現錯誤。

忠告:不要在SSIS中做類型轉換,如果轉換是必需的,那么請使用SSIS表達式做顯式的類型轉換。

 

參考文檔:

SSIS: True/False and 1/0 values on Bit Columns


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM