Is MySQL AUTO_INCREMENT field value alway greater than 0? - mysql

When getting ID from a MySQL table with AUTO_INCREMENT column I always check if it strictly greater than 0.
But recently I was thinking, is it a strict rule for AUTO_INCREMENT?

Default behaviour
It's TRUE for MySQL and MariaDB databases, unless you made some settings manipulation.
There is no clear statement in MySQL docs:
https://dev.mysql.com/doc/refman/8.0/en/example-auto-increment.html
But it can be understood from the description and this phrase:
To start with an AUTO_INCREMENT value other than 1, set that value
with CREATE TABLE or ALTER TABLE, like this
So the default start value is always 1, not 0.
And you can not set the AUTO_INCREMENT column value to 0, unless you set NO_AUTO_VALUE_ON_ZERO:
https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html#sqlmode_no_auto_value_on_zero
By the way, its says:
mysqldump automatically includes in its output a statement that
enables NO_AUTO_VALUE_ON_ZERO
So be careful.
There is an explicit statement in the MariaDB docs:
https://mariadb.com/kb/en/auto_increment/
AUTO_INCREMENT columns start from 1 by default. The automatically
generated value can never be lower than 0.
Overflow
If the value is overflown, it won't set to 0 too:
https://dev.mysql.com/doc/refman/8.0/en/example-auto-increment.html
When the column reaches the upper limit of the data type, the next
attempt to generate a sequence number fails.

Related

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.

Can I use zero in a column which has the AUTO_INCREMENT attribute

I'm using a MySQL 5.0 server. My requirement is to add one special row to an existing table which has an auto-increment primary key.
It would be very useful for future maintenance and management of the project if we were able to make the id of this row 0 (because it's easy to remember and easy to spot in manual observations).
Now, I know that MySQL has no problem with you using your own value for an autoincrement column, and my tests have shown that I can set the autoincrement primary key of a row to 0 with an UPDATE query. However, some concerns have been raised about how this might affect the auto-increment functionality of the column in future INSERTs.
My (limited) experiments have shown nothing strange and I can't find anything specific warning against this in the MySQL docs. That is, apart from this (emphasis mine): http://dev.mysql.com/doc/refman/5.0/en/create-table.html
There can be only one AUTO_INCREMENT column per table, it must be indexed, and it cannot have a DEFAULT value. An AUTO_INCREMENT column works properly only if it contains only positive values. Inserting a negative number is regarded as inserting a very large positive number. This is done to avoid precision problems when numbers “wrap” over from positive to negative and also to ensure that you do not accidentally get an AUTO_INCREMENT column that contains 0.
I am unable to find an explanation for what is wrong with having a value of zero in an AUTO_INCREMENT column, so can anyone tell me if having an AUTO_INCREMENT column that contains 0 is a bad thing?
As you have already discovered, it's not possible to asign a 0 to an auto increment field with an INSERT, you need to use an UPDATE. AFAIK there is nothing wrong with having a 0 in a row except when you try to dump and import. But that can be avoided by first inserting the data and then later marking it as an auto increment field.
Storing 0 is not a recommended practice. For example, if you dump the table with mysqldump and then reload it, MySQL normally generates new sequence numbers when it encounters the 0 values, resulting in a table with contents different from the one that was dumped. Enabling NO_AUTO_VALUE_ON_ZERO before reloading the dump file solves this problem. mysqldump now automatically includes in its output a statement that enables NO_AUTO_VALUE_ON_ZERO, to avoid this problem.

Mysql 5.1.42 alter table auto_increment = 0 doesn't work, truncate does

For my automated acceptance tests, I want inserts to start with id=1.
I achieved this on one PC (XP 32bit, mysql 5.1.something) with (after deleting all rows from the table), "alter table tableName auto_increment = 0".
I'm now setting up a new PC (Windows 7 64bit, mysql 5.1.42), and this command seems to have no effect.
I can see in the information_schema.tables table that the auto_increment value is not changed back to 0 --- it just keeps going up. If I try to change the value in that table directly, I'm told that access is denied to 'root'#'localhost'. Does this perhaps give a hint to my problem?
Other stackoverflow people had suggested that "truncate from tableName" is a good alternative. I'm happy to report that this works. But does anyone know why the "alter table" command won't reset the auto_increment?
Thanks!
NOt sure why it worked on one server, and doesn't work on the other, but the MySQL manual states (quoting, emphasis mine) :
To change the value of the
AUTO_INCREMENT counter to be used
for new rows, do this:
ALTER TABLE t2 AUTO_INCREMENT = value;
You cannot reset the counter to a value less than or equal to any that
have already been used. For
MyISAM, if the value is less than or
equal to the maximum value currently
in the AUTO_INCREMENT column, the
value is reset to the current maximum
plus one. For InnoDB, if the value
is less than the current maximum value
in the column, no error occurs and the
current sequence value is not changed.
Maybe that's the cause of the problem : you are trying to put the auto_increment counter back to 0, but it's already higher than that value -- and as you cannot reset it to a value that's less than any value that's already been used, it doesn't work.