Hey guys I created a database column in my regular LAMP stack that seems to work great, the trouble is when migrating this into CPanel, it seems that my Default values in enum revert to ' ' or whitespace?
the command I used to create this column was
`status` ENUM('0','1','2') NOT NULL DEFAULT '0',
But it seems this doesn't actually happen.....
Is there an error in my syntax? A stupidity of CPanel?
What's going on here?
EDIT
It looks like it has something to do with the input button
submitting a blank value? Anyone heard of this before?
MariaDB [test]> create table settest(attrib set('bold','italic','underline') DEF
AULT 'bold',color enum('red','green','blue') DEFAULT 'blue');
MariaDB [test]> INSERT INTO settest VALUES('a','s');
Query OK, 1 row affected, 2 warnings (0.14 sec)
MariaDB [test]> SHOW WARNINGS;
+---------+------+---------------------------------------------+
| Level | Code | Message |
+---------+------+---------------------------------------------+
| Warning | 1265 | Data truncated for column 'attrib' at row 1 |
| Warning | 1265 | Data truncated for column 'color' at row 1 |
+---------+------+---------------------------------------------+
2 rows in set (0.00 sec)
MariaDB [test]> SELECT * FROM settest;
+--------+-------+
| attrib | color |
+--------+-------+
| | |
| | |
+--------+-------+
Looks like the answer to get a default is NOT NULL DEFAULT 1 as per 1.3. ENUM
Related
I have a table that has nullable columns:
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(255) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
I insert a row with name set to NULL;
INSERT INTO some_table (id, name) VALUES (1, NULL);
Query OK, 1 row affected (0.02 sec)
SELECT * FROM some_table;
+------+------+
| id | name |
+------+------+
| 1 | NULL |
+------+------+
1 row in set (0.01 sec)
If I alter the table's name column to be not-nullable it apparently converts NULL to an empty string:
ALTER TABLE some_table CHANGE COLUMN name name VARCHAR(255) NOT NULL;
Query OK, 1 row affected, 1 warning (0.02 sec)
Records: 1 Duplicates: 0 Warnings: 1
SELECT * FROM some_table;
+------+------+
| id | name |
+------+------+
| 1 | |
+------+------+
1 row in set (0.02 sec)
At this point I would expect an exception to be raised telling me that I have NULL in my dataset and I can not set the column name to NOT NULL.
Is this a configurable option in SQL/MariaDB?
Why is NULL being converted to an empty string?
There is a warning being invoked when altering the table:
SHOW WARNINGS;
+---------+------+-------------------------------------------+
| Level | Code | Message |
+---------+------+-------------------------------------------+
| Warning | 1265 | Data truncated for column 'name' at row 1 |
+---------+------+-------------------------------------------+
1 row in set (0.01 sec)
Version:
SELECT version();
+----------------+
| version() |
+----------------+
| 5.5.62-MariaDB |
+----------------+
1 row in set (0.02 sec)
Apparently, from the documentation for ALTER TABLE, enabling strict mode would prevent your alter statement from succeeding:
This conversion may result in alteration of data. For example, if you shorten a string column, values may be truncated. To prevent the operation from succeeding if conversions to the new data type would result in loss of data, enable strict SQL mode before using ALTER TABLE.
One way to enable strict mode from within MySQL:
SET GLOBAL sql_mode='STRICT_TRANS_TABLES';
See here for other options.
Using 10.3.15-MariaDB-1 on Debian Buster, I cannot reproduce the problem:
MariaDB [foo]> CREATE TABLE some_table(id int(11), name varchar(255));
Query OK, 0 rows affected (0.009 sec)
MariaDB [foo]> INSERT INTO some_table (id, name) VALUES (1, NULL);
Query OK, 1 row affected (0.003 sec)
MariaDB [foo]> SELECT * FROM some_table;
+------+------+
| id | name |
+------+------+
| 1 | NULL |
+------+------+
1 row in set (0.000 sec)
MariaDB [foo]> ALTER TABLE some_table CHANGE COLUMN name name VARCHAR(255) NOT NULL;
ERROR 1265 (01000): Data truncated for column 'name' at row 1
MariaDB [foo]> SELECT * FROM some_table;
+------+------+
| id | name |
+------+------+
| 1 | NULL |
+------+------+
1 row in set (0.000 sec)
MariaDB [foo]> SELECT version();
+-------------------+
| version() |
+-------------------+
| 10.3.15-MariaDB-1 |
+-------------------+
1 row in set (0.000 sec)
If possible, I suggest you update your MariaDB version. It seems very old to me.
I do not know if this is expected behaviour or a bug but it seems incorrect. Using MySQL 5.7.9 from the Ubuntu 14.04 ondrej PPA.
Summary: an operation which should raise a warning (inserting an implicit NULL into a not null column) raises an error, only if the table has a trigger defined.
select ##sql_mode;
+------------------------+
| ##sql_mode |
+------------------------+
| NO_ENGINE_SUBSTITUTION |
+------------------------+
1 row in set (0.00 sec)
show global variables like 'sql_mode';
+---------------+------------------------+
| Variable_name | Value |
+---------------+------------------------+
| sql_mode | NO_ENGINE_SUBSTITUTION |
+---------------+------------------------+
1 row in set (0.00 sec)
show variables like 'sql_mode';
+---------------+------------------------+
| Variable_name | Value |
+---------------+------------------------+
| sql_mode | NO_ENGINE_SUBSTITUTION |
+---------------+------------------------+
1 row in set (0.00 sec)
create table _test (col_1 varchar(20) not null, col_2 varchar(20) not null) engine=myisam charset=utf8;
Query OK, 0 rows affected (0.00 sec)
show columns from _test;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| col_1 | varchar(20) | NO | | NULL | |
| col_2 | varchar(20) | NO | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
insert into _test (col_1) values ('abc');
Query OK, 1 row affected, 1 warning (0.00 sec)
^^^^^^^^^ This is expected behaviour ^^^^^^^^^
delimiter $$
create trigger `insert_test` before insert on `_test` for each row begin set NEW.col_1 = concat(NEW.col_1, '+test'); end$$
Query OK, 0 rows affected (0.02 sec)
delimiter ;
insert into _test (col_1) values ('abc');
ERROR 1048 (23000): Column 'col_2' cannot be null
^^^^^^^^^ This is UNexpected behaviour ^^^^^^^^^
Thus the same command in the same mode has a different end-state when a trigger is set.
Can anyone see a mistake in this, has anyone experienced similar or is this a bug in the release?
Update
Having tested the same process in 5.6.19 (also on Ubuntu 14.04) the final line returns:
insert into _test (col_1) values ('abc');
Query OK, 1 row affected, 1 warning (0.01 sec)
Which once again is expected behaviour.
Update 2
This has been submitted as a bug to the MySQL development team and is now at verified status.
I'm using MySQL on a CentOS server from a website running Apache and Perl. I'm seeing this behavior (mocked up):
mysql> describe product;
+-------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(10) | YES | | NULL | |
+-------+------------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
mysql> insert into product (name) values ('Widget');
Query OK, 1 row affected (0.00 sec)
mysql> insert into product (name) values ('Thing');
Query OK, 1 row affected (0.00 sec)
mysql> select * from product;
+----+--------+
| id | name |
+----+--------+
| 1 | Widget |
| 2 | Widget |
| 3 | Thing |
+----+--------+
3 rows in set (0.00 sec)
My theory is that the Perl CGI script may be executed concurrently (perhaps due to double click, browser refresh, etc.) so the insert gets performed twice. This is fairly rare but causes problems when it happens.
In cases where this happens, all columns except 'id' have identical values. Other than column 'id' duplicate values are allowed.
Is there a way to prevent this behavior?
If you installed Perl, Apache, and MySQL from CentOS repositories and didn't make any radical configuration changes, it's highly unlikely you've found a bug in the platform. Are you using mod_perl or PSGI or is it definitely CGI? Have you installed any Perl modules from CPAN sources or has everything been installed through yum?
A stupid solution you might consider implementing is generating some kind of nonce (one-time-use string or number) in your script, adding a column for it and a unique index on that column to your table, and inserting it along with the rest of the form data. If you catch a duplicate key error, just disregard it. That won't explain what's happening but it will prevent it from happening.
I made a table which name is 'test' in mysql in my PC like belows.
create table test(
telnum varchar(20) not null,
reg_date datetime not null default '0000-00-00 00:00:00',
remarks text,
primary key(telnum)
);
And I uploaded a file named 1.txt into table 'test'.
1.txt's contents are like belows :
01011112222
01022223333
01033334444
And 'load data infile' syntax are like belows :
load data infile "c:/temp/1.txt"
ignore into table test;
But there is a problem.
Every phone numbers were cut like below.
Query OK, 3 rows affected, 3 warnings (0.00 sec)
Records: 3 Deleted: 0 Skipped: 0 Warnings: 3
mysql> select * from test;
+-------------+---------------------+---------+
| telnum | reg_date | remarks |
+-------------+---------------------+---------+
|12222 | 0000-00-00 00:00:00 |
|23333 | 0000-00-00 00:00:00 |
|34444 | 0000-00-00 00:00:00 |
+-------------+---------------------+---------+
3 rows in set (0.00 sec)
Only 5 characters are remained from 11 characters.
6 characters disappeared.
And second problem is 'warnings'. Reason of warnings is like below.
mysql> show warnings;
+---------+------+---------------------------------------------------+
| Level | Code | Message |
+---------+------+---------------------------------------------------+
| Warning | 1264 | Out of range value for column 'reg_date' at row 1 |
| Warning | 1264 | Out of range value for column 'reg_date' at row 2 |
| Warning | 1264 | Out of range value for column 'reg_date' at row 3 |
+---------+------+---------------------------------------------------+
3 rows in set (0.00 sec)
I did'nt put anything into the reg_date field.
But the message says out of range value for column 'reg_date'.
What are the reasons and how can I solve these problems?
Try to change the line delimiter. On Windows it's usually \r\n rather then \n which is default if you omit LINES TERMINATED BY clause
LOAD DATA INFILE "/tmp/1.txt"
IGNORE INTO TABLE test
LINES TERMINATED BY '\n'
MySQL documentation says that since 5.0, varchar lengths refer to character units, not bytes. However, I recently came across an issue where I was getting truncated data warnings when inserting values that should have fit into the varchar column it was designated.
I replicated this issue with a simple table in v5.1
mysql> show create table test\G
*************************** 1. row ***************************
Table: test
Create Table: CREATE TABLE `test` (
`string` varchar(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
I then inserted multiple 10 characters values with differing amounts of UTF8 characters
mysql> insert into test (string) values
-> ('abcdefghij'),
-> ('ãáéíçãáéíç'),
-> ('ãáéíç67890'),
-> ('éíç4567890'),
-> ('íç34567890');
Query OK, 5 rows affected, 4 warnings (0.06 sec)
Records: 5 Duplicates: 0 Warnings: 4
mysql> show warnings;
+---------+------+---------------------------------------------+
| Level | Code | Message |
+---------+------+---------------------------------------------+
| Warning | 1265 | Data truncated for column 'string' at row 2 |
| Warning | 1265 | Data truncated for column 'string' at row 3 |
| Warning | 1265 | Data truncated for column 'string' at row 4 |
| Warning | 1265 | Data truncated for column 'string' at row 5 |
+---------+------+---------------------------------------------+
mysql> select * from test;
+------------+
| string |
+------------+
| abcdefghij |
| ãáéíç |
| ãáéíç |
| éíç4567 |
| íç345678 |
+------------+
5 rows in set (0.00 sec)
I think that this shows that the varchar size is still defined in bytes or at least, is not accurate in character units.
The question is, am I understanding the documentation correctly and is this a bug? Or am I misinterpreting the documentation?
It's true that VARCHAR and CHAR sizes are considered in characters, not bytes.
I was able to recreate your issue when I set my connection character set to latin1 (single byte).
Ensure that you set your connection character set to UTF8 prior to running the insertion query with the following command:
SET NAMES utf8
If you don't do this, a two-byte UTF8 character will get sent as two single-byte characters.
You might consider changing your default client character set.