SQLite 中是不是可以进行十进制数约束?

Posted

技术标签:

【中文标题】SQLite 中是不是可以进行十进制数约束?【英文标题】:Is decimal number constraint possible in SQLite?SQLite 中是否可以进行十进制数约束? 【发布时间】:2021-11-14 12:36:26 【问题描述】:

问题

我正在使用 SQLite,我有一堆字段表示以毫米为单位的度量,我想限制为小数点后 1 个数字(例如 1.2 ; 12.2 ; 122.2 等等)。

我见过诸如将DECIMAL(n,1) 作为类型的例子,我试过了,但它似乎没有限制值(我想这是因为它不是实际的 SQLite 类型)。

我需要迁移到 mysql 才能工作吗?


编辑(找到解决方案)

我使用了 Dan04 的回答:它很简单,而且效果很好:

► 表格如下:

CREATE TABLE demo(
a REAL CHECK(a = ROUND(a,1)),
b REAL CHECK(b = ROUND(b,1)),
c REAL GENERATED ALWAYS AS (a+b)
)

► 插入相关数据:INSERT INTO demo (a,b) values (41.4,22.6)

► 插入错误数据:INSERT INTO demo (a,b) values (1.45,22.68) 输出:

Execution finished with errors.
Result: CHECK constraint failed: a = ROUND(a,1)
At line 1:
insert into demo (a,b) values (1.45,22.68)

【问题讨论】:

你不能在应用程序级别这样做吗? 你的意思是像CREATE TABLE demo(mm REAL NOT NULL CHECK(cast(mm * 10 as 'int') == mm * 10)) 这样防止输入超过1 个小数点后的数字吗? 【参考方案1】:

MySQL 的DECIMAL(nn,1) 将四舍五入到小数点后一位用于存储。这与约束不同。

显示数据时,您的应用应该将结果四舍五入到有意义的精度。 (可以说小数点后一位对于天气读数来说是多余的。)

一般来说,测量值(不是钱)应该存储在FLOAT 中。这种数据类型(在 MySQL 和许多其他产品中)提供 7 个“有效数字”和相当高的值范围。

FLOAT用于经纬度时有足够的精度来区分两辆车,但不足以区分两个拥抱的人。

(对不起,我不能代表 SQLite。如果FLOAT 可用,那么我建议您使用它并在输出上四舍五入。)

【讨论】:

【参考方案2】:

您可以使用the ROUND function 创建CHECK 约束。将列声明为:

mm REAL CHECK(mm = ROUND(mm, 1))

但请注意,底层表示仍然是二进制浮点数,通常需要注意准确性。

【讨论】:

这正是我想要的!多谢 ! :-)

以上是关于SQLite 中是不是可以进行十进制数约束?的主要内容,如果未能解决你的问题,请参考以下文章

在 SQLite 上转换表达式结果,从浮点数到十进制数

位运算:二进制中1的个数

在EF中复制的SQL中添加十进制数的方法是什么?

C语言 判断一个数的二进制数第7位是不是为1

十六进制转换十进制(JAVA版)

怎么计算二进制数的运算