Is there an engine for MySQL/MariaDB that enforces CHECK? - mysql

I know that InnoDB enforces foreign key. Is there a engine for MySQL/MariaDB that really implements CHECK?
Suppose I create a table with the following command:
create table a(t timestamp not null, check (t > '2014-05-01')) ENGINE=InnoDB;
and I try to insert a row that is suppose to be invalid:
insert into a(t) values('2014-01-01');
MySQL, using InnoDB, allow the insertion of that invalid row. I would like to use an engine that would not accept that insert. Is there an engine for that job?

CHECK constraint works as expected in MariaDB 10.2, which is currently beta.
https://jira.mariadb.org/browse/MDEV-7563

There is no such engine in MySQL. If you must check at the database level, your only option is to use triggers and validate the data there.
Maybe one day though:
http://bugs.mysql.com/bug.php?id=3464

Related

How to delete when primary key contains two columns, and using safe mode

My table is created like this:
CREATE TABLE test(
num1 INT,
num2 INT,
PRIMARY KEY(num1, num2)
);
what should my delete query look like?
using
DELETE FROM test WHERE num1=1 AND num2=2;
only result in this error message:
Error Code: 1175. You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column To disable safe mode, toggle the option in Preferences -> SQL Editor and reconnect.
Also, before you ask, I do know how to turn safe update mode off, but that does not answer my question.
I've seen some other Stack Overflow posts where people complain that MySQL Workbench is blocking them from performing safe updates inappropriately.
But I just tried it with your table, both with the PK columns and with a non-key column. When safe mode is enabled, it blocks me from doing updates via non-key column, as it should. But I don't get the error you described.
I'm using MySQL Workbench 6.3.8 and MySQL Server 8.0.0-dmr.
Perhaps this is a bug in an old version of MySQL or an old version of MySQL Workbench.
Updated mysql and the error is gone.
what a waste of my time.

Is mysql compatible with sql-92?

The other day I was trying to create a table in mysql usign a standard syntax:
create table client(
rc character varying(11)
constraint client_pk primary key
);
However, mysql doesn't support setting a primary key this way. (I'm 99% sure it's compliant with the sql-92 norm)
So my question: Does MySQL fail to support at even these basic things from a 20 year old standard, or am I missing something?
EDIT: my goal is NOT to create this table using using some mysql dialect, but to create this table using a standardized syntax. And the question is whether it is possible.
To answer your question, no, MySQL is not fully compliant with the SQL-92 specification, in that MySQL supports only a subset of the specification, and MySQL has some significant(ly useful) extensions which are not part of the SQL-92 specification.
This is not just about the SQL syntax that MySQL accepts and recognizes, but (the probably bigger issue) is about what MySQL actually does with the syntax, the actual operations that MySQL performs with the syntax that it does accept. That's really a more important issue than the more superficial issue of what syntax MySQL recognizes.
It's not that MySQL is lazy. And it's not that MySQL just doesn't care.
There is an entire section of the MySQL documentation devoted to MySQL differences from the SQL standard. And the most important differences aren't really about syntax, but rather about that fact that "MySQL performs operations differently in some cases."
For example, MySQL accepts syntax for CHECK constraints, but MySQL does not actually do any checking or make any attempt to enforce CHECK constraints. MySQL accepts syntax that meets the SQL-92 specification, but the behavior of MySQL is much different from other databases that accept that same syntax.
As another example, the behavior of MySQL with respect to FOREIGN KEY constraints differs significantly, depending on whether the storage engine for the table is MyISAM or InnoDB.
To get your CREATE TABLE statement to execute in MySQL, you would need to change it.
It looks like the easiest option for you would be to remove constraint client_pk from the sql text. You can either specify the table constraint in the column definition:
create table client(
rc character varying(11) primary key
);
or declare the table constraint separately"
create table client(
rc character varying(11),
primary key (rc)
);
Both of those forms are entirely compatible with the SQL-92 specification.
Note that MySQL does accept the syntax for constraint name definition, when the declaration of the constraint is not on the column, e.g.
create table client(
rc character varying(11),
constraint client_pk primary key (rc)
);
And that syntax is also entirely compatible with SQL-92 specifiction.
But note that MySQL ignores the supplied constraint name, and assigns the name PRIMARY to the primary key constraint. And this is true even if the constraint is declared in a separate ALTER TABLE statement.
Note that the syntax that MySQL accepts, and in some cases the operations it performs, is dependent on the settings of specific MySQL variables, in particular, sql_mode, and of particular concern, in the case of your statement, the setting of the default-storage-engine variable, and whether this table will be created using the MyISAM engine or the InnoDB engine, or even the corner case that default-storage-engine has been set to BLACKHOLE.
I understand that your goal is to "create this table with standardized syntax".
But I think you really DO need to be concerned with at least some minimum subset of MySQL specific syntax, in as far as the variety of possible behaviors that MySQL can exhibit when presented with "standardized syntax". Consider:
SET default-storage-engine = 'MyISAM' ;
SET default-storage-engine = 'InnoDB' ;
SET sql_mode = '' ;
SET sql_mode = 'ANSI' ;
This works for me in MySQL 5.5.29:
create table client(
rc character varying(11),
constraint client_pk primary key(rc)
);
However, as a_horse_with_no_name has pointed out, MySQL ignores the client_pk name and calls it PRIMARY.
References:
http://savage.net.au/SQL/sql-92.bnf.html
http://owen.sj.ca.us/~rk/howto/sql92.html
create table tablename
(
column_Name varchar(20) not null,
column_Name varchar(20),
primary key(column_name)
);
In this way you can create table and set primary key.

NO foreign keys created though I created them . It shown me no error while executing the query. but now showing no foreign keys for my schema

I executed script related to create my database ..it executed successfully. but no foreign keys created . I am using cent os . mysql 5.0.
If the DB engine is one that does not support FK, it will show you no errors, but won't create them. For example, MyIsam.
Choose InnoDB as the table type to be able to create FK on it.
are the tables in MyISAM instead of InnoDB?
MyISAM don't support foreign keys.

MySQL: Check constraint with Date

I am using MySQL and here is a simple query set:
create table dcheck (
fdate date,
sdate date,
check (fdate <= sdate)
);
insert into dcheck values ('2006-12-12','2003-12-12');
insert into dcheck values ('2003-12-12', '2006-12-12');
Here I expect the first insert statement to fail. But surprisingly, both the queries passes and two rows are there in the table.
Can anyone please explain why?
Thanks
MySQL doesn't implement CHECK constraints. From the latest (5.6) fine manual:
The CHECK clause is parsed but ignored by all storage engines.
So the syntax is parsed for compatibility other other SQLs but the checking is not implemented.
You could fake your CHECK constraint with BEFORE INSERT and BEFORE UPDATE triggers that threw an exception if the desired condition was not met.
The CHECK clause is parsed but ignored by all storage engines.
http://dev.mysql.com/doc/refman/5.1/en/create-table.html
CHECK constraints are now supported since MySQL 8.0.16

Determine InnoDB FK Constraints without information_schema

I'm writing some code to inspect a MySQL database structure, and need information about Foreign Key constraints (on InnoDB tables).
There are two ways I know of to do this:
Parse the results of SHOW CREATE TABLE X
Use INFORMATION_SCEMA.REFERENTIAL_CONSTRAINTS
Unfortunately option two requires MySQL 5.1.16 or later, so I can't use it unless/until I can convince our server guy to update, And while I can probably get away with option 1, it feels messy and without writing a full SQL parser I wouldn't feel sure my code would always work with any table.
Is there another way of getting at this information?
Thanks
From the MySQL 5.0 manual online:
You can also display the foreign key constraints for a table like
this:
SHOW TABLE STATUS FROM db_name LIKE 'tbl_name';
The foreign key constraints are listed in the Comment column of the
output.
Poster indicates that this doesn't provide ON UPDATE and ON DELETE information which is an important part of foreign key behavior.
Another option:
Since you control the code involved, is it possible to set up another MySQL instance in the same environment which is version 5.1+? If so, let's call that instance dummy. Run the SHOW CREATE TABLE on the live database. Then, on dummy run a DROP TABLE IF EXIST followed by the output from the SHOW CREATE TABLE query.
Now you can use INFORMATION_SCHEMA on the dummy database to get the information.