Mysql enum field problems - mysql

in a mysql table I have a field of type Enum ('S', 'N') with default value = S. Now I have checked this table and I find many records that have no value in this field. How is it possible? I wanted to force the values of this field to be only S and N. Where did I go wrong?
Mysql version 5.0.92
my field definition:
`conteggia` enum('S','N') NOT NULL default 'S'

From the Empty or NULL Enumeration Values documentation:
If you insert an invalid value into an ENUM (that is, a string not present in the list of permitted values), the empty string is inserted instead as a special error value. ...
If strict SQL mode is enabled, attempts to insert invalid ENUM values result in an error.
So you must not have strict mode enabled, and due to some error in your code it assigned invalid values to the column.

Related

How restrict mysql tiny-int to accept just integer

Im trying to get eeror about invalid data for a query but it seems mysql accept strings as tiney in queries and set 0 instead of returning any error.
So how can I restrict it to just accept integers.
Thanks in advance.
This is SQL Mode-dependent.
In strict mode you must receive either 'Data truncated' (inserted value starts from numeric chars) or 'Incorrect integer value' (first symbol is not numeric) error message, and none data must be inserted.
If strict mode is disabled then warning is generated instead of error, and the value is converted to numeric (all symbols starting from first non-numeric one are truncated, then the value is converted to number, if it is empty string then zero is assigned).
Data type checking (and convertion if needed) is performed firstly, even before BEFORE INSERT trigger.
DEMO

Incorrect decimal (integer) value: ' ' mySQL

In mySQL workbench database, one of the tables has latitude, longitude and district attributes
lat: decimal (10,8)
lng: decimal (11,8)
district: int(4)
I'm trying to import data from .csv file to this table
ERROR 1366: 1366: Incorrect decimal value: '' for column 'lat' at row 1
SQL Statement:
ERROR 1366: 1366: Incorrect integer value: '' for column 'district' at row 1
SQL Statement:
INSERT INTO `db`.`myTable` (`id`, `name_en`, `icon`, `lat`, `lng`, `district`, `city`, `postal_code`)
VALUES ('686', 'Name',?, '', '', '','1', 'P.O. Box 1111')
You have strict sql mode enabled, and you try to pass an empty string ('') as value for decimal fields in the insert. Empty string is an invalid value for a numeric field and in strict sql mode mysql generates an error if you try to insert an invalid data into a column, rather than providing a warning and use the default value (0 for numeric columns) of the particular column's data type:
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.
Remove the strict sql mode for the session before starting the import:
SET SESSION sql_mode = ''
Remove STRICT_TRANS_TABLE from global sql_mode. You might required other attributes such as NO_ZERO_DATE in global sql_mode if already set.
Set this under [mysqld] in my.cnf (or /etc/mysql/mysql.conf.d/mysqld.cnf) depending on your server version.
[mysqld]
sql_mode = "NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
All I did was change my query from INSERT INTO... to INSERT IGNORE INTO... Worked perfectly.

Is a non-nullable, MySQL enum column guaranteed to only contain those values?

If I have a column in a MySQL database that is:
Non-nullable
Is an ENUM with 5 possible values
Has a default value of 1 of those ENUM's
Can it be guaranteed that there can never be a value in that column apart from one of those ENUM's?
Not by default - there is one more value your column can have in addition to the values of the enum, an empty string in the column.
You have to enable strict SQL mode in MySQL to have the guarantee that only the enum values (or NULL if the column is nullable ) can occur.
Taken from here
If you insert an invalid value into an ENUM (that is, a string not
present in the list of permitted values), the empty string is inserted
instead as a special error value. This string can be distinguished
from a “normal” empty string by the fact that this string has the
numeric value 0. See Section 11.4.4, “ Index Values for Enumeration
Literals ” for details about the numeric indexes for the enumeration
values.
If strict SQL mode is enabled, attempts to insert invalid ENUM values
result in an error.
If strict SQL mode is enabled, attempts to insert invalid ENUM values result in an error.
Source

Writing to a MySQL ENUM column by index using ODBC

From the MySQL reference manual:
If you store a number into an ENUM column, the number is treated as the index into the possible values, and the value stored is the enumeration member with that index.
But when I try to write an SQL_SMALLINT value to that ENUM column using ODBC I get the error HY000:1:1265 (Data truncated for column ...).
So how can I write a number into a MySQL ENUM column using ODBC, such that this number is interpreted as the enum index?
Edit: Some more information
The column is defined as:
`TrackState` ENUM('NEWE','NEWN','VALID','INVISIBLE','CLOSED','DIED') NULL
and the statement used with ODBC is:
INSERT INTO test (TrackState) VALUES (?)
and in my C code I use SQLBindParameter with SQL_C_USHORT and SQL_SMALLINT to bind an unsigned short variable.
When I change my TrackState column to an ordinary INT column, the numeric value (which I want to be interpreted as the index of an enum) is successfully written.

MySQL Enum's always contain '' (empty string) in possibilities

I'm trying to create a simple 'yes'/'maybe'/'no' Enum in MySQL with PhpMyAdmin
I set NULL to No, and 'maybe' as the default value
I am expecting an error when executing something like "SET EnumCol=''", because '' (an empty string) should not be a valid value.
But the query gets executed and the value gets set to '' - which means I'm forced to double check for this unwanted and illegal value whenever I read from the database!
Is this a bug in MySQL or PhpMyAdmin?
Does anyone know a way of disabling this behavior?
Thanks.
Empty string is error indicator of invalid values in ENUM. From mysql ENUM type manual:
If you insert an invalid value into an ENUM (that is, a string not present in the list of allowed values), the empty string is inserted instead as a special error value. This string can be distinguished from a “normal” empty string by the fact that this string has the numerical value 0. More about this later.
To disable this behaviour:
If strict SQL mode is enabled, attempts to insert invalid ENUM values result in an error.
To enable strict mode see Server SQL Modes.
ENUM's are a pain in the butt. unless you also need to set the value by a number, i would stay away from them.
instead, use a varchar column with a foreign key to a lookup table to restrict the values. that will make it impossible to insert a bad value.