我在MySQL中看到一些与用户创建的函数相关的奇怪行为。我会尽可能简化这一点。
mysql> SELECT 1 / 50
+--------+
| 1/50 |
+--------+
| 0.0200 |
+--------+
1 row in set (0.00 sec)
到目前为止一切顺利。现在我创建一个函数来进行这个除法并调用函数:
mysql> delimiter $$
mysql> create function myd(var decimal) returns decimal language sql deterministic
-> begin
-> declare res decimal;
-> set res = var / 50;
->
-> return res;
-> end
-> $$
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> select myd(1);
+--------+
| myd(1) |
+--------+
| 0 |
+--------+
1 row in set (0.00 sec)
很奇怪。好吧,让我们尝试一些其他的值:
mysql> select myd(10), myd(20), myd(50), myd(70), myd(100);
+---------+---------+---------+---------+----------+
| myd(10) | myd(20) | myd(50) | myd(70) | myd(100) |
+---------+---------+---------+---------+----------+
| 0 | 0 | 1 | 1 | 2 |
+---------+---------+---------+---------+----------+
1 row in set (0.00 sec)
我做了一些测试 - 但是从结果可以清楚地看出函数的结果被舍入为整数值,尽管函数被声明为returns decimal
。我尝试将decimal
替换为float
,但这并没有改变。
那么为什么要进行这种舍入,更重要的是,我该如何预防呢?
答案 0 :(得分:5)
答案 1 :(得分:0)
需要指定分数:
mysql> SELECT 1/2 ;
+--------+
| 1/2 |
+--------+
| 0.5000 |
+--------+
mysql> SELECT CAST(1 / 50 AS DECIMAL);
+-------------------------+
| CAST(1 / 50 AS DECIMAL) |
+-------------------------+
| 0 |
+-------------------------+
1 row in set (0.00 sec)
mysql> SELECT CAST(1 / 50 AS DECIMAL(10,2));
+-------------------------------+
| CAST(1 / 50 AS DECIMAL(10,2)) |
+-------------------------------+
| 0.02 |
+-------------------------------+
答案 2 :(得分:0)
无精度声明的十进制表示0精度。
mysql> select CAST(1/50 as Decimal);
+-----------------------+
| CAST(1/50 as Decimal) |
+-----------------------+
| 0 |
+-----------------------+
1 row in set (0.00 sec)
mysql> select CAST(1/50 as Decimal(10,4));
+-----------------------------+
| CAST(1/50 as Decimal(10,4)) |
+-----------------------------+
| 0.0200 |
+-----------------------------+
1 row in set (0.00 sec)
如果将其更改为float或decimal(10,4),它将起作用。
mysql> delimiter $$
mysql> create function myd6(var float) returns float language sql deterministic begin declare res float; set res = var / 50; return res; end$$
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> select myd6(1);
+----------------------+
| myd6(1) |
+----------------------+
| 0.019999999552965164 |
+----------------------+
1 row in set (0.00 sec)