2013-11-27 4 views
5

Я вижу странное поведение в MySQL, связанное с создаваемыми пользователем функциями. Я упрощу это, насколько это возможно.Функция 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, но это немного изменилось.

Так почему это округление происходит и, что более важно, как я могу его предотвратить?

ответ

5

Если вы не указали точность для десятичного знака, то по умолчанию будет DECIMAL(M,0), который равен цифр после запятой.

Пример: Определить его как

decimal(10,3) 

иметь 3 цифры после запятой.

Source

+0

Ах! Хорошо, дайте мне посмотреть :) –

+0

Прохладный! вот и все. –

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 | 
+-------------------------------+ 
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) 

Если вы измените его на плавающий или десятичный (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) 
+0

RE: «если вы перейдете на квартиру, это сработает» - пожалуйста, полностью прочтите мой вопрос. Я сказал там: «Я попытался заменить тип decimal на float, но это немного изменилось». –

+0

@AleksG, но он работает, как показано в отрывке в моем ответе? – DhruvPathak

Смежные вопросы