I notice a very weird problem in my code. I am inserting a value of 128 but in my database it says 127.
I'd like to look at the mysql general/query logs however i dont ever see any log files produce no matter what i do. I tried -l , -l with an absolute path and --general_log_file. No luck. I also used mysqladmin flush-logs. Still nothing
Are you using a signed TINYINT datatype by any chance?
CREATE TABLE my_table (id TINYINT);
Query OK, 0 rows affected (0.03 sec)
INSERT INTO my_table VALUES (128);
Query OK, 1 row affected, 1 warning (0.00 sec)
SELECT * FROM my_table;
+------+
| id |
+------+
| 127 |
+------+
1 row in set (0.00 sec)
Related
I have a mysql table which has a data structure as follows,
create table data(
....
name char(40) NULL,
...
)
But I could insert names which has characters more than 40 in to name field. Can someone explain what is the actual meaning of char(40)?
You cannot insert a string of more than 40 characters in a column defined with the type CHAR(40).
If you run MySQL in strict mode, you will get an error if you try to insert a longer string.
mysql> create table mytable ( c char(40) );
Query OK, 0 rows affected (0.01 sec)
mysql> insert into mytable (c) values ('Now is the time for all good men to come to the aid of their country.');
ERROR 1406 (22001): Data too long for column 'c' at row 1
If you run MySQL in non-strict mode, the insert will succeed, but only the first 40 characters of your string is stored in the column. The characters beyond 40 are lost, and you get no error.
mysql> set sql_mode='';
Query OK, 0 rows affected (0.00 sec)
mysql> insert into mytable (c) values ('Now is the time for all good men to come to the aid of their country.');
Query OK, 1 row affected, 1 warning (0.01 sec)
mysql> show warnings;
+---------+------+----------------------------------------+
| Level | Code | Message |
+---------+------+----------------------------------------+
| Warning | 1265 | Data truncated for column 'c' at row 1 |
+---------+------+----------------------------------------+
1 row in set (0.00 sec)
mysql> select c from mytable;
+------------------------------------------+
| c |
+------------------------------------------+
| Now is the time for all good men to come |
+------------------------------------------+
1 row in set (0.00 sec)
I recommend operating MySQL in strict mode (strict mode is the default since MySQL 5.7). I would prefer to get an error instead of losing data.
I have a mysql table with a decimal(16,2) field. Seems like the addition operation with another decimal(16,2) field string can cause the Data truncated for column x at row 1 issue, which raises exception in my django project.
I'm aware of multiplication or division operation of that field can cause this issue bacause the result is probably not fit in decimal(16,2) definition, but does the addition and subtraction operation the same?
My MySQL server version is 5.5.37-0ubuntu0.14.04.1. You can reproduce this issue from bellow:
mysql> drop database test;
Query OK, 1 row affected (0.10 sec)
mysql> create database test;
Query OK, 1 row affected (0.00 sec)
mysql> use test;
Database changed
mysql> create table t(price decimal(16,2));
Query OK, 0 rows affected (0.16 sec)
mysql> insert into t values('2004.74');
Query OK, 1 row affected (0.03 sec)
mysql> select * from t;
+---------+
| price |
+---------+
| 2004.74 |
+---------+
1 row in set (0.00 sec)
mysql> update t set price = price + '0.09';
Query OK, 1 row affected (0.05 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> update t set price = price + '0.09';
Query OK, 1 row affected, 1 warning (0.03 sec)
Rows matched: 1 Changed: 1 Warnings: 1
mysql> show warnings;
+-------+------+--------------------------------------------+
| Level | Code | Message |
+-------+------+--------------------------------------------+
| Note | 1265 | Data truncated for column 'price' at row 1 |
+-------+------+--------------------------------------------+
1 row in set (0.00 sec)
mysql> select * from t;
+---------+
| price |
+---------+
| 2004.92 |
+---------+
1 row in set (0.00 sec)
There are two problems:
You are not storing decimal values, you're trying to store string/varchar, which is converted into double value by mysql, for example following code does not give errors update t set price = price + 0.09; (even executed several times)
Anyway this code gives expected warning (note number) update t set price = price + 0.091; you can change it to update t set price = price + cast(0.091 as decimal(16,2)); of course with cast you can use string values too update t set price = price + cast('0.09' as decimal(16,2));
In my case problem occurs when I try to insert a decimal with 3 digits after the the dot like: 0.xxx on a column defined as DECIMAL(10,2)
I changed it to DECIMAL(10,3) OR used php to enter values like 0.xx on DECIMAL(10,2) table
Using a decimal (I have tried variations of it) 0.5 is always converted to 5.
I can store 1.5, etc, no problem... Just curious on how I need to set up my data type to correctly store a '0.5' number.
Thanks
EDIT:
The current data type is Decimal (3,1). I have tried float as well.
I simply retreive the number through $_POST from a Form text box which is restricted to numbers only through Java. I never considered that maybe the browser is simply sending it as a 5, I don't know.
EDIT 2: I have confirmed through echo that the 0.5 is sent fine, it's once it gets into the database that it becomes 5
You know, I might get voted down for this, but I've always had success (as a sort of hack) in storing values like this as a VARCHAR and then using format() function in PHP when I need to make calculations. MySQL still seems to parse it well enough for SQL functions as well. Just my 2 cents :)
I used a decimal value in a database with various inputs:
I have tried to recreate you issue, but I get the following:
mysql> create table test(myDec decimal(2,2));
Query OK, 0 rows affected (0.02 sec)
mysql> insert into test values(0.5);
Query OK, 1 row affected (0.01 sec)
mysql> insert into test values(.5);
Query OK, 1 row affected (0.00 sec)
mysql> select * from test;
+-------+
| myDec |
+-------+
| 0.50 |
| 0.50 |
+-------+
2 rows in set (0.00 sec)
Given your edit, I think that you might be getting values from international visitors, where the decimal point might be formatted using a comma instead of a dot?
mysql> insert into test values('0,5');
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> select * from test;
+-------+
| myDec |
+-------+
| 0.50 |
| 0.50 |
| 0.00 |
+-------+
3 rows in set (0.00 sec)
From my create table script, I've defined the hasMultipleColors field as a BIT:
hasMultipleColors BIT NOT NULL,
When running an INSERT, there are no warnings thrown for this or the other BIT fields, but selecting the rows shows that all BIT values are blank.
Manually trying to UPDATE these records from the command line gives odd effect - shows that the record was match and changed (if appropriate), but still always shows blank.
Server version: 5.5.24-0ubuntu0.12.04.1 (Ubuntu)
mysql> update pumps set hasMultipleColors = 1 where id = 1;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 1 Changed: 0 Warnings: 0
mysql> select hasMultipleColors from pumps where id = 1;
+-------------------+
| hasMultipleColors |
+-------------------+
| |
+-------------------+
1 row in set (0.00 sec)
mysql> update pumps set hasMultipleColors = b'0' where id = 1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select hasMultipleColors from pumps where id = 1;
+-------------------+
| hasMultipleColors |
+-------------------+
| |
+-------------------+
1 row in set (0.00 sec)
Any thoughts?
You need to cast the bit field to an integer.
mysql> select hasMultipleColors+0 from pumps where id = 1;
This is because of a bug, see: http://bugs.mysql.com/bug.php?id=43670. The status says: Won't fix.
You can cast BIT field to unsigned.
SELECT CAST(hasMultipleColors AS UNSIGNED) AS hasMultipleColors
FROM pumps
WHERE id = 1
It will return 1 or 0 based on the value of hasMultipleColors.
You need to perform a conversion as bit 1 is not printable.
SELECT hasMultipleColors+0 from pumps where id = 1;
See more here:
http://dev.mysql.com/doc/refman/5.0/en/bit-field-literals.html
The actual reason for the effect you see, is that it's done right and as expected.
The bit field has bits and thus return bits, and trying to output a single bit as a character will show the character with the given bit-value – in this case a zero-width control character.
Some software may handle this automagically, but for command line MySQL you'll have to cast it as int in some way (e.g. by adding zero).
In languages like PHP the ordinal value of the character will give you the right value, using the ord() function (though to be really proper, it would have to be converted from decimal to binary string, to work for bit fields longer than one character).
EDIT:
Found a quite old source saying that it changed, so a MySQL upgrade might make everything work more as expected: http://gphemsley.wordpress.com/2010/02/08/php-mysql-and-the-bit-field-type/
We are using MySql 5.0 on Ubuntu 9.04. The full version is: 5.0.75-0ubuntu10
I created a test database. and a test table in it. I see the following output from an insert statement:
mysql> CREATE TABLE test (floaty FLOAT(8,2)) engine=InnoDb;
Query OK, 0 rows affected (0.02 sec)
mysql> insert into test value(858147.11);
Query OK, 1 row affected (0.01 sec)
mysql> SELECT * FROM test;
+-----------+
| floaty |
+-----------+
| 858147.12 |
+-----------+
1 row in set (0.00 sec)
There seems to be a problem with the scale/precision set up in mySql...or did I miss anything?
UPDATE:
Found a boundary for one of the numbers we were inserting, here is the code:
mysql> CREATE TABLE test (floaty FLOAT(8,2)) engine=InnoDb;
Query OK, 0 rows affected (0.03 sec)
mysql> insert into test value(131071.01);
Query OK, 1 row affected (0.01 sec)
mysql> insert into test value(131072.01);
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM test;
+-----------+
| floaty |
+-----------+
| 131071.01 |
| 131072.02 |
+-----------+
2 rows in set (0.00 sec)
mysql>
Face Palm!!!!
Floats are 32 bit numbers stored as mantissa and exponents. I am not 100% sure how MySql will split the storage but taking Java as an example they would use 24 bits for a signed mantissa and 8 bits for an exponent (scientific notation). This means that the maximum value a FLOAT can have is +8388608*10^127 and the minimum is -8388608*10^127. This means only 7 significant digits, and my FLOAT definition used 8.
We are going to switch all of these 8,2 to DOUBLE from FLOAT.
MySQL docs mention "MySQL performs rounding when storing values" and I suspect this is the issue here. I duplicated your issue but changed the storage type to be DOUBLE:
CREATE TABLE test (val, DOUBLE);
and the retrieved value matched the test value you provided.
My suggestion, for what it's worth, is use DOUBLE or maybe DECIMAL. I tried the same original test with:
CREATE TABLE test (val, DECIMAL(8,2));
and it retrieved the value I gave it: 858147.11.