Unable to add new column due to invalid datetime default value - mysql

In my table, I have two columns along with others. These two columns are of DATETIME type, and their value is set to 0000-00-00 00:00:00 by the previous programmer. Now I just want to add columns with int datatype. However everytime I click save in phpMyAdmin, it says the previous two table are of invalid default value.
So I click on one of them to set the default to none namely registerDate and LastLoginDate columns. Whenever I click save on registerDate, it says LastLoginDate has invalid default value, and whenever I click save on LastLoginDate, it says registerDate has invalid default value. Basically I'mm just unable to change the default value in these two columns, also unable to add any other column.
I did refer to these, but they somehow don't help to solve my issue:
MySQL default datetime through phpmyadmin
MySQL - Cannot insert NULL value in column, but I have a default value specified?
Invalid default value for 'dateAdded'

Probably a combination of no_zero_date and strict sql modes are enabled (depending on your exact MySQL version) preventing MySQL to use '0000-00-00' as a default value. I would disable the strict sql mode using SET SESSION sql_mode = '...'; command (but make note of the exact sql mode setting), then I would change the table not to use zero date as default, then you can restore the sql mode setting.

Related

MySQL error column cannot be null although default value set

I recently moved my SQL Database to another Amazon RDS server with version 5.7.
Before that, the application was working fine but now I started logging errors:
"ER_BAD_NULL_ERROR: Column xyz cannot be null" - The column already has a default value CURRENT_TIMESTAMP
I checked online and people suggested to have the sql_mode equal to NO_ENGINE_SUBSTITUTION
I checked the existing settings and it is already like that.
Any other reason I am getting this error? Any tricks?
Thanks.
After searching more, the problem was only in timestamp fields with current_timestamp default value. I searched in the parameters and found explicit_defaults_for_timestamp that was enabled (value 1) and with a bit more research, I had to disable this parameter as per the documentation here
https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_explicit_defaults_for_timestamp
in order to get the required result and fix the problem.
Simply deactivate explicit_defaults_for_timestamp
SET GLOBAL explicit_defaults_for_timestamp = 0;
I have no idea why it works like that in this particular case, so I would concentrate on fixing a problem.
According to the docs NO_ENGINE_SUBSTITUTION has nothing to do with the error, during application run. I would select rows with column "xyz" of NULL value and update it to something - not null.
Default is applied when row is created. Let's say you have a table with some millions of rows, and want to add column with not null. That would block your table for significant amount of time. So you can create column without not null, but with default. That operation deals only with metadata, so is fast. Default will deal with all new rows. After that you can slowly update all rows. At the end not null constraint can be added. Not sure if DB is checking constraint when adding it at last step. Or maybe prev. version had problem with it? With MySQL things like that happens.

Mysql: Not getting an error when updating a NOT NULL column to null

Why does mysql accepts null data when updating a not null column and then converts the data to 0.
I am expecting an error it just does not show up. How can I get an error if someone tries to update a not null column to null? I need it so I can rollback the transaction if I get an error.Is there any configuration needed within the database to do this? Thank you
You've not specified which version of Mysql you're using, and in which mode. I'll answer this assuming you're running Mysql 5.7 without strict mode.
Strict mode controls how MySQL handles invalid or missing values in data-change statements such as INSERT or UPDATE. A value can be invalid for several reasons. For example, it might have the wrong data type for the column, or it might be out of range. A value is missing when a new row to be inserted does not contain a value for a non-NULL column that has no explicit DEFAULT clause in its definition. (For a NULL column, NULL is inserted if the value is missing.) Strict mode also affects DDL statements such as CREATE TABLE.
If strict mode is not in effect, MySQL inserts adjusted values for invalid or missing values and produces warnings (see Section 13.7.5.40, “SHOW WARNINGS Syntax”). In strict mode, you can produce this behavior by using INSERT IGNORE or UPDATE IGNORE.
Source: https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sql-mode-full
I recommend you to enable strict mode (STRICT_ALL_TABLES) and fix your application to support it; this will also enforce other query limitations where people are most commonly hit by ONLY_FULL_GROUP_BY.
To set the SQL mode at server startup, use the --sql-mode="modes" option on the command line, or sql-mode="modes" in an option file such as my.cnf (Unix operating systems) or my.ini (Windows). modes is a list of different modes separated by commas. To clear the SQL mode explicitly, set it to an empty string using --sql-mode="" on the command line, or sql-mode="" in an option file.
To change the SQL mode at runtime, set the global or session sql_mode system variable using a SET statement:
SET GLOBAL sql_mode = 'modes';
SET SESSION sql_mode = 'modes';
Source: https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sql-mode-setting
Why does mysql accepts null data when updating a not null column and
then converts the data to 0.
You question is not clear as we need the DDL of the table and the update , but as from what you are saying, Well logically because the column not null has a default value 0. check the below example.
create table Test_table ( name varchar(100) null , position_s varchar(100) default 'Y' not null)
SQL>
Table created
insert into Emp_table (name) values('Me')
SQL>
1 row inserted
SQL>
NAME POSITION_S
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
Me Y
#aaron0207 #Moudiz I am using laravel and updates data like this.
$specificReservation = Reservation::where('reference_id',$reference_id)->first();
$specificReservation->res_status = 1;
$specificReservation->payment_id = null;
$specificReservation->save();
I also tried to update manually in the database with this
UPDATE reservations SET payment_id = null
and it also shows no error so I think this is a database problem.

Timestamp in mysql column

I'm uploading a datababase to MySQL and get this problem:
ERROR 1293 (HY000) at line 31: Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
The problem is that of two columns with "Timestamp" data type in that table, only one should have "Current Timestamp" value, while the other default value is "null". When I upload the database, both columns' value get changed to "Current Timestamp", which makes the process of exporting and importing very annoying, since I have to manually change it back to null before importing again.
Any idea why it automatically changes to "current timestamp"? This is an Amazon EC2 linux instance (see attached mysql version)
Before version 5.6, MySQL makes an assumption when you declare a timestamp column... specifically, it assumes the first timestamp column on a table will be the one that has the automatic update attributes.
If you don't explicitly disable the behavior on the first timestamp, it's implicitly enabled, which causes the explicit automatic value on a later timestamp to be rejected. It isn't enough not to ask.
It need not be the first TIMESTAMP column in a table that is automatically initialized or updated to the current timestamp. However, to specify automatic initialization or updating for a different TIMESTAMP column, you must suppress the automatic properties for the first one. Then, for the other TIMESTAMP column, the rules for the DEFAULT and ON UPDATE clauses are the same as for the first TIMESTAMP column, except that if you omit both clauses, no automatic initialization or updating occurs.
To suppress automatic properties for the first TIMESTAMP column, do either of the following:
Define the column with a DEFAULT clause that specifies a constant default value.
Specify the NULL attribute. This also causes the column to permit NULL values, which means that you cannot assign the current timestamp by setting the column to NULL. Assigning NULL sets the column to NULL.
— https://dev.mysql.com/doc/refman/5.5/en/timestamp-initialization.html
So, for your first timestamp -- if it's not the one you want to be the automatic timestamp -- use either one of these column type declarations (they're identical):
TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00'
TIMESTAMP NOT NULL DEFAULT 0 -- automatically expanded to '0000-00-00 00:00:00'
This should allow you to copy this table definition between systems without issue.
This silliness was fixed in MySQL Server 5.6, where the system variable explicit_defaults_for_timestamp disables the implicit automatic behavior for the first timestamp in a table.
If you start a server running 5.6 without setting this option, a warning is written to the error log.
[Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please
use --explicit_defaults_for_timestamp server option (see documentation
for more details).
The warning is reminding you that you still have the legacy behavior, which is deprecated in 5.6.

Omitting a "NOT NULL" value during an INSERT defaults it to 0. Why? [duplicate]

This question already has an answer here:
Preventing MySQL from inserting implicit default values into not null columns
(1 answer)
Closed 9 years ago.
I have the following table structure:
badge_id and interface_id are primary keys.
When I attempt an INSERT operation specifying only the badge_id, I expected it to fail, but instead interface_id defaults to 0.
I'm running the following versions:
Could somebody explain why it defaults to zero? Shouldn't this fail?
Thanks in advance.
The answer is in the documentation for CREATE TABLE:
If a column definition includes no explicit DEFAULT value, MySQL
determines the default value as described in Section 11.5, “Data Type
Default Values”.
More information is available in Data type default values:
Implicit defaults are defined as follows: For numeric types, the
default is 0, with the exception that for integer or floating-point
types declared with the AUTO_INCREMENT attribute, the default is the
next value in the sequence.
Check this out: http://dev.mysql.com/doc/refman/5.0/en/data-type-defaults.html
As of MySQL 5.0.2, if a column definition includes no explicit DEFAULT value, MySQL determines the default value as follows:
If the column can take NULL as a value, the column is defined with an explicit DEFAULT NULL clause. This is the same as before 5.0.2.
If the column cannot take NULL as the value, MySQL defines the column with no explicit DEFAULT clause. For data entry, if an INSERT or REPLACE statement includes no value for
the column, MySQL handles the column according to the SQL mode in effect at the time:
If strict SQL mode is not enabled, MySQL sets the column to the implicit default value for the column data type.

MySQL Timestamp field

Is it possible to set a field to Timestamp but not have it change on update to current timestamp?
I'm trying to do that using phpMyAdmin and it doesn't let me remove the default on update CURRENT_TIMESTAMP
See this question and answer: Support user time zones
I am trying to use the TIMESTAMP as it will allow me to play around with the timezones easily.
Is it not possible to keep the data in that field intact when updating the same row?
This is the behaviour of TIMESTAMP. It can be confusing alright. Read this to work through it. Alternatively consider using a DATETIME.
The server allows any combination of DEFAULT and ON UPDATE, if phpMyAdmin doesn't let you set it, then it's maybe a bug in phpMyAdmin. Anyway, it's important to note that timestamp columns are treated specially in mysql, so if you have more than one of this type in your table, it's well possible that it's not gonna work the way you expect.
From the mysql docs:
In a CREATE TABLE statement, the first TIMESTAMP column can be declared in any of the following ways:
With both DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP clauses, the column has the current timestamp for its default value, and is automatically updated.
With neither DEFAULT nor ON UPDATE clauses, it is the same as DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP.
With a DEFAULT CURRENT_TIMESTAMP clause and no ON UPDATE clause, the column has the current timestamp for its default value but is not automatically updated.
With no DEFAULT clause and with an ON UPDATE CURRENT_TIMESTAMP clause, the column has a default of 0 and is automatically updated.
Use the command interface.
Looks like you must specify an "DEFAULT CURRENT_TIMESTAMP" attribute on table creation to get that behaviour.
documentation here.