I'm getting warnings when updating a table but the warnings are not showing. Through tedious and lengthy trial-and-error, the cause of the warnings has been tracked down to the INNER JOIN. I need a better way to debug a warning.
Setup is OK. I know warnings are on because MySQL command prompt was started with option '--show-warnings' and warnings are turned on warnings with '\W':
mysql> \W
Show warnings enabled.
mysql> show variables like '%warn%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_warnings | 0 |
| sql_warnings | ON |
| warning_count | 0 |
+---------------+-------+
3 rows in set (0.01 sec)
To make sure warnings were on, I forced a truncating warning on a VARCHAR(255) field:
mysql> UPDATE course
-> SET course.transcript_title = 'Field transcript_title is VARCHAR(255). This is over 255 characters to force truncating warning. Field transcript_title is VARCHAR(255). This is over 255 characters to force truncating warning. Field transcript_title is VARCHAR(255). This is over 255 characters to force truncating warning.'
-> WHERE course.title LIKE '%SLP%'
-> AND course.year = 2008
-> AND course.gid = 35;
Query OK, 104 rows affected, 104 warnings (0.19 sec)
Rows matched: 104 Changed: 104 Warnings: 104
Warning (Code 1265): Data truncated for column 'transcript_title' at row 1
Warning (Code 1265): Data truncated for column 'transcript_title' at row 2
.... etc.
I want to get the warning from this type of query:
mysql> UPDATE course
-> INNER JOIN group_info ON course.gid = group_info.id
-> SET course.description = 'Foo.'
-> WHERE course.title LIKE '%SLP%'
-> AND course.year = 2008 AND group_info.id = 35;
Query OK, 0 rows affected (0.02 sec)
Rows matched: 104 Changed: 0 Warnings: 104
mysql> SHOW WARNINGS;
Empty set (0.00 sec)
From trial and error, I know the error is from having the INNER JOIN clause. If I remove the INNER JOIN and directly use the gid (group id) field in the course table, then no warnings:
mysql> UPDATE course
-> SET course.description = 'Bar.'
-> WHERE course.title LIKE '%SLP%'
-> AND course.year = 2008
-> AND course.gid = 35;
Query OK, 104 rows affected (0.01 sec)
Rows matched: 104 Changed: 104 Warnings: 0
But I need the INNER JOIN clause because what I really want to do is use the more friendly 'name' field in the joined 'group_info' table:
UPDATE course
INNER JOIN group_info ON course.gid = group_info.id
SET course.description = 'Foo.'
WHERE course.title LIKE '%SLP%'
AND course.year = 2008
AND group_info.name = 'One-to-One Meeting Time';
I've been googling, reading, and debugging the warning for over 1 hour. I've searched for answers or explanations for why this would not show warnings but no luck.
How do I get warnings to show for the INNER JOIN type of UPDATE?
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 need to login with an case-insensitive email ID.My mail ID is stored in an encrypted format I am fetching from a database with something like the following query:
$this->db->select('Name');
$this->db->from('users');
$this->db->where('emailId',"AES_ENCRYPT('{$emailId}','/*awshp$*/') ", FALSE);
$query = $this->db->get();
$result = $query->row();
return $result;
I am using binary but no use
it's have simple logic, While you sign up store hash value of email id after convert it to lowercase. and on login also convert it to lowercase.so if user enter email id in any case,encryption string match.
AES encryption is a two-way algorithm, meaning you can recover the original value, so you can also update existing records that don't conform to the format you want to test.
After you run the update in the database, just apply the suggestions made by Tim Biegeleisen and you should be good to go.
Demo for updating existing records
mysql> CREATE TABLE t1 (
-> email VARBINARY(256)
-> );
Query OK, 0 rows affected (0.31 sec)
mysql> INSERT INTO t1 (email) VALUES
-> (AES_ENCRYPT('MiXeDcAsEdEmAiL#gmail.com','salt')),
-> (AES_ENCRYPT('UPPERCASEDEMAIL#gmail.com','salt')),
-> (AES_ENCRYPT('lowercasedemail#gmail.com','salt'));
Query OK, 3 rows affected (0.09 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> UPDATE t1 SET email = AES_ENCRYPT(LOWER(CAST(AES_DECRYPT(email,'salt') AS CHARACTER)),'salt');
Query OK, 2 rows affected (0.11 sec)
Rows matched: 3 Changed: 2 Warnings: 0
mysql> SELECT CAST(aes_decrypt(email,'salt') AS CHARACTER) lower_cased from t1;
+---------------------------+
| lower_cased |
+---------------------------+
| mixedcasedemail#gmail.com |
| uppercasedemail#gmail.com |
| lowercasedemail#gmail.com |
+---------------------------+
3 rows in set (0.00 sec)
NB
Don't forget to change the update statement to match your column name and the value you use as a salt.
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
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/
Certainly a noobish question, but I got to ask: :-) Assuming a column of type varchar and length 255 and the longest string stored in a row at this column shold have length 200. What happens, if I altered the columns length to less then 200? Would the strings all get "cut"?
By default, it will allow you to alter the column, it will truncate strings longer than the new length, and it will generate a warning.
mysql> create table t (v varchar(20));
Query OK, 0 rows affected (0.06 sec)
mysql> insert into t values ('12345678901234567890');
Query OK, 1 row affected (0.00 sec)
mysql> alter table t modify column v varchar(10);
Query OK, 1 row affected, 1 warning (0.04 sec)
Records: 1 Duplicates: 0 Warnings: 1
mysql> show warnings;
+---------+------+----------------------------------------+
| Level | Code | Message |
+---------+------+----------------------------------------+
| Warning | 1265 | Data truncated for column 'v' at row 1 |
+---------+------+----------------------------------------+
1 row in set (0.00 sec)
mysql> select * from t;
+------------+
| v |
+------------+
| 1234567890 |
+------------+
1 row in set (0.00 sec)
If you have the SQL mode STRICT_ALL_TABLES or STRICT_TRANS_TABLES set, the warning becomes an error and the ALTER will fail.
mysql> alter table t modify column v varchar(10);
ERROR 1265 (01000): Data truncated for column 'v' at row 1