我正忙着尝试使用ADODB作为向客户编写准备好的脚本的方法。数据库,因为它比使用sqlcmd的批处理脚本无限好。
早期我注意到有时ADODB结果会与osql或sqlcmd给出的结果不同,并且在进一步调查中我发现它似乎总是在包含布尔值的列中。如果我运行以下代码,我得到-1:
declare @test bit
set @test=1
select top 1 @test
逻辑上,根据MSDN和w3schools文档,它应返回1,SQL服务器上的位数据类型保持为1,0或null。
有人能解释导致这种情况的原因以及如何预防吗?
如果导入也是通过ADODB完成的,那么从我的数据库导出信息然后导入-1而不是1会导致问题吗?
答案 0 :(得分: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 Server数据类型位映射到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&当你隐式地将它们转换为整数时,它反过来对应于整数0和-1。
您可以通过在即时窗口中发出以下命令来证明这一点。
Debug.Print CInt(False)
Debug.Print CInt(True)
在实际建议方面,这给你留下了什么,我不确定,但你应该将这些值视为代码中的布尔变量,而不是数字。
幸运的是,SQL Server会在数据库端隐含地将-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)
希望这能解决比造成的更多混乱