2013-11-27 10 views
5

Sto vedendo alcuni strani comportamenti in MySQL relativi alle funzioni create dall'utente. Lo semplificherò il più possibile.Funzione MySQL - risultati di divisione sconosciuti?

mysql> SELECT 1/50 

+--------+ 
| 1/50 | 
+--------+ 
| 0.0200 | 
+--------+ 
1 row in set (0.00 sec) 

Fin qui tutto bene. Ora creo una funzione per fare questa divisione e chiamare la funzione:

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) 

Molto strano. Ok, proviamo un paio di altri valori:

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) 

ho fatto un po 'di più test - ma è abbastanza chiaro dai risultati che il risultato della funzione viene arrotondato a un valore intero, nonostante la funzione viene dichiarata come returns decimal. Ho provato a sostituire il tipo decimal con float ma questo non è cambiato un po '.

Quindi perché si verifica questo arrotondamento e, cosa più importante, come impedirlo?

risposta

5

Se non si specifica una precisione per un decimale, sarà DECIMAL(M,0) per impostazione predefinita che è zero cifre dopo la virgola.

Esempio: Definire come

decimal(10,3) 

per avere 3 cifre dopo la virgola.

Source

+0

Ah! Ok, fammi vedere :) –

+0

Cool! era così. –

0

necessità di specificare frazione:

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

decimale dichiarato senza precisione significa 0 precisione.

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) 

Se lo si modifica in virgola mobile o decimale (10,4), funzionerà.

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: "se cambi in flat funzionerà" - per favore leggi completamente la mia domanda. Ho affermato che "ho provato a sostituire il decimale tipo con float ma non è cambiato un po '". –

+0

@AleksG, ma funziona come mostrato nello snippet nella mia risposta? – DhruvPathak

Problemi correlati