COM-объект ADODB возвращает -1 для битовых значений 1
Я занят экспериментированием с ADODB как средством написания готовых сценариев в клиентских базах данных, поскольку это намного лучше, чем пакетные сценарии с использованием sqlcmd.
Ранее я заметил, что иногда результаты ADODB будут отличаться от результатов, полученных с помощью osql или sqlcmd, и при дальнейшем исследовании я обнаружил, что они всегда выглядят в столбцах, которые содержат логическое значение. Если я запускаю следующий код, я получаю -1:
declare @test bit
set @test=1
select top 1 @test
Когда логически он должен возвращать 1, как в соответствии с документацией MSDN и w3schools, битовый тип данных на сервере SQL содержит 1, 0 или ноль.
Может ли кто-нибудь объяснить, что вызывает это и как это предотвратить?
Будет ли экспорт информации из моей базы данных, а затем импорт -1, а не 1 причиной проблем, если импорт также выполняется с помощью ADODB?
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 aren't получает прямой перевод на цифры 0 и -1 по ADODB.
Они фактически переводятся в False & True, которые в свою очередь соответствуют целым числам 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)
Надеюсь, это решило больше путаницы, чем вызвало