In the docs for STRICT_ALL_TABLES
it states,
For
STRICT_ALL_TABLES
, MySQL returns an error and ignores the rest of the rows. However, because the earlier rows have been inserted or updated, the result is a partial update. To avoid this, use single-row statements, which can be aborted without changing the table.
What does this mean though?
CREATE TABLE foo ( a int NOT NULL );
INSERT INTO foo VALUES (NULL), (NULL);
This does what everyone would reasonably expect a totally insane database to do,
SELECT * FROM foo;
+---+
| a |
+---+
| 0 |
| 0 |
+---+
2 rows in set (0.00 sec)
But, I expected a multi-row INSERT
to insert the non-violating rows that are seen first,
SET sql_mode='STRICT_ALL_TABLES';
INSERT INTO foo VALUES (5), (NULL);
To insert just one row with 5
, as per the docs in STRICT_ALL_TABLES
. Instead it does,
ERROR 1048 (23000): Column 'a' cannot be null
How do I interpret the docs to STRICT_ALL_TABLES
when they say earlier rows .. partial update and "single-row statements". And why is MySQL doing something less horrible then documented? I'm pleasantly surprised.
Best Answer
I agree that the split between
_ALL_
and_TRANS_
needs clarification.Earlier on that page it says
I think the meat of the issue is InnoDB versus MyISAM.
MyISAM is covered by
STRICT_ALL_TABLES
, but not bySTRICT_TRANS_TABLES
. If anUPDATE
orDELETE
is aborted for any reason mid-stream, some rows will have been updated or deleted. You have no practical way to clean up the mess. (This is a major reason never to use MyISAM.)InnoDB is covered by both settings, but
STRICT_TRANS_TABLES
is more relevant, and overrides the statement about "earlier rows".UPDATE
andDELETE
are atomic.Also involved is the question of aborting with an error versus doing something so you can keep going. For example, bad dates and defaults without an explicit
DEFAULT
, etc. These are cases where MySQL (unlike some other engines) defines that a non-abort action will be taken.If your Question is intended to point out poor phrasing in the documentation, go for it. But do it at bugs.mysql.com , where there is a chance of it getting fixed.
MySQL 8.0 moves toward more robust default settings by changing the defaults.