如何从TINYINT(1)列中检索int值而不是布尔值?

7

我有一个被指定为MySQL列的:

`type` TINYINT(1) NOT NULL DEFAULT '0'

该列的意图是存储一个不超过127的整数值,因为预计不会有太多对象“类型”。
我在其中一行的字段中存储了“2”。
使用SqlYog,简单的SELECT type FROM table查询可以得到正确的结果,即2。
然而,使用Connector/Net 6.1.2(诚然,它有点过时,当前版本是6.5.4),会发生以下情况:
var Temp = Reader["type"].GetType(); // equals "Boolean"

这种类型的列通常用于布尔值,但在这种情况下,我想获得整数值。以下方法未能产生预期结果:
int i = Reader.GetInt32("type"); // equals 1 (should be 2)

在.NET应用程序中使用Connector/Net从TINYINT(1)列获取int值的正确方法是什么?

这是使用MySQL版本5.5.16


你是对的,TINYINT 通常用于布尔类型。我建议只使用普通的 INTEGER 类型字段,存储空间不会那么昂贵。 ;) - Jesse Webb
你尝试过使用 SELECT CAST(type AS SIGNED) AS type FROM table 吗? - Eugen Rieck
1
存储不是问题,但我更关心速度/性能。如果我知道特定值永远不会超过限制,我会尝试适当地调整列的大小。(这就是为什么我的 int 列并非全部都是 BIGINT 的原因 :))也许我应该只使用 SMALLINT 并结束它,但我想了解更多关于这种情况的技术背景。 - JYelton
@Eugen 我还没有 - 我正在设计表格的过程中,以便有选择地指定列类型,从而使不必要的查询变得不再重要。我只是因为偶然发现这个问题而有点(过度?)好奇。 - JYelton
如果您使用Reader.GetValue()Reader.GetSByte()而不是Reader.GetInt32()会发生什么? - ypercubeᵀᴹ
@ypercube:看起来.GetSByte()可以工作。.GetValue()没有,但它仍然返回一个布尔值。 - JYelton
3个回答

5
将此内容放入连接字符串中,以使用tinyint作为数字。
TreatTinyAsBoolean=false

这个的官方文档可以在http://dev.mysql.com/doc/refman/5.5/en/connector-net-connection-options.html找到。谢谢提示。 - JYelton

4
连接器困惑的答案可能在MySQL文档; 数字类型中的这部分:

从MySQL 5.0.3开始,有一个BIT数据类型可用于存储位字段值。(在5.0.3之前,MySQL将BIT解释为TINYINT(1).) ...

或者(更有可能的是)来自数字类型概述中的这部分:

BOOL, BOOLEAN

这些类型是TINYINT(1)的同义词。零的值被认为是假的。非零值被认为是真的...


我认为这相当完整地回答了问题的“为什么”。它解释了为什么连接器的结果与Sqlyog的结果不同。它也基本上告诉我要使用TINYINT(2)(或更大的“显示宽度”)作为解决方法。 - JYelton

3

我找到的一个解决方案是将列类型简单地更改为UNSIGNED

`type` tinyint(1) unsigned NOT NULL DEFAULT '0'

这将产生以下影响:

var Temp = Reader["type"].GetType(); // equals "Byte"

调用.GetInt32()方法将返回正确的结果(2)。

然而,如果您想存储从-127到127的值(使用它作为带符号的 TINYINT ),则此解决方案不起作用。


另一种解决方案是将列类型更改为 TINYINT(2) :

`type` tinyint(2) NOT NULL DEFAULT '0'

这会提供以下内容:
var Temp = Reader["type"].GetType(); // equals "SByte"

此外,还能产生正确的结果(2)。

然而,这引出了在 TINYINT 后面的数字(即 TINYINT(#)) 的目的是什么的问题。难道不是为了“可选地指定显示宽度”吗?也许有人可以在这一点上提供更多的信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接