我正在Visual Studio 2010中处理Web应用程序。正在使用SQL Server 2008写入和读取数据库表。
我有一个数据库表myTable
,其数据类型为myColumn
的列bit
。我像这样在Web应用程序上写此专栏:
UPDATE myTable
SET myColumn = 1
这很好,并且使用SQL Server Management Studio,我可以看到该列已更新为 TRUE ,正如我期望的那样。
在我的网络应用的另一部分中,我查询表的方式如下:
sqlCmd.CommandText = "SELECT myColumn FROM myTable"
sqlRdr = sqlCmd.ExecuteReader()
While sqlRdr.Read
myColumn = sqlRdr(0)
End While
运行此查询时,myColumn
设置为-1。这是怎么发生的?根据{{3}},有点是
整数数据类型,其值可以为1、0或NULL。
和
可以将字符串值TRUE和FALSE转换为位值:将TRUE转换为1,将FALSE转换为0。
我不明白如何从此查询中获得myColumn = -1
。
答案 0 :(得分:1)
获取bit
列的数据时,实际上是一个32位数字,而不仅仅是一个位。在该32位数字中,每个位都设置为1或每个位都设置为0。使用二进制补码转换为Integer
时的值11111111 11111111 11111111 11111111为-1,因为第一位是符号位。
问题在于您不应该在VB代码中使用Integer
。您应该使用1或0表示此数据的唯一时间是SQL代码中的文字值。在您的VB代码中,应该使用Boolean
来表示此数据,因为该数据是什么。 1代表True
,0代表False
,如果您在SQL Server Management Studio中查看数据,将会看到。
这意味着这里:
sqlCmd.CommandText = "SELECT myColumn FROM myTable"
sqlRdr = sqlCmd.ExecuteReader()
While sqlRdr.Read
myColumn = sqlRdr(0)
End While
myColumn
变量应为Boolean
类型。该代码无论如何都不应该编译,因为它需要Option Strict Off
,并且您应该几乎总是拥有Option Strict On
。您不应将从数据读取器获得的Object
引用分配给类型为Integer
或Boolean
的变量。您应该使用数据读取器来获取数据的实际类型。如果您确实得到了Integer
:
myColumn = sqlRdr.GetInt32(0)
但是,正如您将正确执行并使用Boolean
一样:
myColumn = sqlRdr.GetBoolean(0)
如果您想保存数据,那么通常会使用参数,例如
sqlCmd.CommandText = "UPDATE myTable SET myColumn = @myColumn"
sqlCmd.Parameters.Add("@myColumn", SqlDbType.Bit).Value = True
sqlCmd.ExecuteNonQuery()
答案 1 :(得分:0)
True的值为-1,False为0
Debug.Print(Val(True) & " " & Val(False))
答案 2 :(得分:0)
SQL位类型映射到.Net系统布尔类型(真/假)。
您的代码,
myColumn = sqlRdr(0)
使用VB规则进行隐式类型转换。假设myColumn
是整数类型,而sqlRdr(0)
返回的Object变量类型是布尔值。 VB将true映射为-1,将false映射为0。
如果要使用System.Convert.ToInt32
进行布尔到整数的转换,则在转换布尔型真值时会收到一(1)的值。
myColumn = System.Convert.ToInt32(sqlRdr(0))
请注意,如果您使用VB的首选CInt
函数或Ctype
函数,您还将收到-1值。