SSIS 处理 bit 列

时间:2024-01-21 21:51:28

一般的编程语言,例如,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输出的结果,避免出现错误。

 

参考文档:

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