ADODB COM 对象 returns -1 位值为 1

ADODB COM Object returns -1 for bit values of 1

我正忙着尝试使用 ADODB 作为一种在客户数据库上编写准备好的脚本的方法,因为它比使用 sqlcmd 编写批处理脚本要好得多。

早些时候我注意到有时 ADODB 结果与 osql 或 sqlcmd 给出的结果不同,在进一步调查中我发现它似乎总是在包含布尔值的列中。如果我 运行 以下代码我得到 -1:

declare @test bit
set @test=1
select top 1 @test

根据 MSDN and w3schools 文档,SQL 服务器上的位数据类型在逻辑上应该 return 1 为 1、0 或 null。

谁能解释是什么原因造成的以及如何预防?

如果导入也是使用 ADODB 完成的,那么从我的数据库导出信息然后导入 -1 而不是 1 会导致问题吗?

演示代码

ConnectionString = "Provider=SQLNCLI11;"
ConnectionString = ConnectionString & "Server=localhost;"
ConnectionString = ConnectionString & "Database=master;"
ConnectionString = ConnectionString & "Trusted_Connection=yes;"

Dim Conn As Object
Set Conn = CreateObject("ADODB.Connection")
Conn.Open ConnectionString
Set Recordset = Conn.Execute("SELECT convert(bit, 1) as bit")

MsgBox Recordset.Fields("bit").Type, 0, "FieldType"
MsgBox VarType(Recordset.Fields("bit").Value),0,"VarType"

这表明 SQL 服务器数据类型位映射到枚举值 11 ADODB.DataTypeEnum.adBoolean https://msdn.microsoft.com/en-us/library/ms675318(v=vs.85).aspx

这又对应于 Vartype 11 的变体 (VariantType.vbBoolean) https://msdn.microsoft.com/en-us/library/32bbtt2s(v=vs.90).aspx 因此位值 0 和 1 不会被 ADODB 直接转换为数字 0 和 -1。

它们实际上被转换为 False 和 True,当您将它们隐式转换为整数时,它们又对应于整数 0 和 -1。

您可以通过立即 window 发出以下命令来证明这一点。

Debug.Print CInt(False)
Debug.Print CInt(True)

就实际建议而言,我不确定这给您留下了什么,但您可能应该在代码中将这些值视为布尔变量而不是数字。

幸运的是SQL服务器会在数据库端将 -1 隐式转换回 1,因此您无需担心

 DECLARE @table table (b bit)
 INSERT @table  (b) VALUES(-1)
 SELECT b from @table

给你

(1 row(s) affected)
b
-----
1

(1 row(s) affected)

希望这解决了比它造成的更多的混乱