邏輯類型是最常用的數據類型之一,一般編程語言,例如,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表達式做顯式的類型轉換。
參考文檔: