一般的编程语言,例如,C#、Java和R等都有布尔类型,用于表示逻辑真(true)和假(false),SQL Server没有布尔类型,但是,在编程时,可以使用bit 类型来代替,bit类型只有两个有效值:0 和 1。在设计数据表时,使用0代表逻辑假,使用1代表逻辑真。SSIS引擎内置有布尔类型,SSIS自动把bit 类型转换成布尔类型,把 1 转换成 True,把0 转换成False。
bit类型的0和1,跟整数类型的0和1是不同的:
- 当把整数类型转换为bit类型时,整数0转换为bit类型的0,非整数0转换为bit类型的1。
- 当把bit类型转换为整数类型时,bit类型的0转换为整数0,bit类型的1转换为整数类型的1。
但是,当SSIS把布尔类型转换为整数类型时,情况跟你想象的不同:
- False会转换为整数0
- True会转换为整数-1
一,把bit类型转换为布尔类型
在SSIS Package中,外部数据流的类型会自动转换,由外部数据源的类型转换为SSIS支持的数据类型。如果外部数据源是SQL Server,列的数据类型是bit,那么Package在加载数据和输出数据时自动进行类型转化,把 1 转换成 True,把0 转换成False,转换过程是透明的。如果要把SQL Server 的Bit 类型转换成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类型:
3,查看插入的结果
从SQL Server数据库中查看插入的结果,当把外部数据源的Bit类型的数据转换为smallint时,SSIS 把0(bit)转变成 0(smallint),却把1(bit)转换成 -1(smallint),这是一个错误,但是SSIS不会抛出任何异常消息:
4,故障排除
产生错误的根本原因是SSIS引擎无法直接把类型DT_BOOL直接转换为类型DT_I2,为了排除这种错误,用户可以使用派生列,显式转换数据类型,转换的表达式是:
(DT_I2)(IsMerged ? 1 : 0)
三,数据类型系统
SSIS引擎对数据类型的处理流程是
- 在加载数据时,SSIS把外部数据源的数据加载到缓存中,把外部数据源的类型转换为SSIS支持的数据类型,类型以DT_xxxx命名。
- 在输出数据时,SSIS把缓存的数据输出到外部的目标容器中,把SSIS的数据类型转换为外部数据支持的数据类型;
在数据类型的转换过程中,开发人员需要明确知道类型转换的结果,即使SSIS引擎不抛出任何异常,也要复查Package输出的结果,避免出现错误。
参考文档: