ALL,
igor#IgorDellGentoo ~ $ isql myodbc-5.2-test root wasqra
+---------------------------------------+
| Connected! |
| |
| sql-statement |
| help [tablename] |
| quit |
| |
+---------------------------------------+
SQL> use draft;
SQLRowCount returns 0
SQL> ALTER TABLE owners ADD FOREIGN KEY id REFERENCES leagues(id);
[ISQL]ERROR: Could not SQLExecute
SQL>
What am I doing wrong?
Also, for some reason I can't create a foreign key thru the mySQL-Workbench when creating the table.
There is no "Add" button or "+" sign to add this constraint. And there is no reaction on the right click.
Could someone please point me to the right direction?
I have Workbench version 6.3.4.0 on Gentoo Linux.
SQL> show tables;
+-----------------------------------------------------------------+
| Tables_in_draft |
+-----------------------------------------------------------------+
| leagues |
| owners |
+-----------------------------------------------------------------+
SQLRowCount returns 2
2 rows fetched
SQL> SELECT * FROM leagues;
+-----------+-----------------------------------------------------------------------------------------------------+-----------+------------+-----------+-----------+-----------+-------------+
| id | name | drafttype | scoringtype| roundvalue| leaguetype| salary | benchplayers|
+-----------+-----------------------------------------------------------------------------------------------------+-----------+------------+-----------+-----------+-----------+-------------+
+-----------+-----------------------------------------------------------------------------------------------------+-----------+------------+-----------+-----------+-----------+-------------+
seems you are using id as a foreign key use proper column instead
ALTER TABLE owners
ADD COLUMN FOREIGNID INT NOT NULL;
ALTER TABLE owners
ADD FOREIGN KEY (FOREIGNID) REFERENCES leagues(ID);
Related
I've create a table called Students.
It has 4 fields: Name, Age, Class, Years.
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| Name | varchar(50) | NO | PRI | NULL | |
| Age | smallint | YES | | 18 | |
| Class | varchar(10) | YES | | NULL | |
| Years | smallint | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
I have added a CHECK CONSTRAINT on Years field that means that the value in Years column can't be lower than 3.
I did it by
mysql> alter table Students
-> add constraint CK_Years check (Years >= 3);
My goal here is to insert a query with a record which has a Years value of 2, which means it won't pass the CK_Years check constraint.
I want to do it without changing the constraint or the fields in the insert statement.
Is it possible?
mysql> insert into Students
-> (Name, Age, Class, Years) values ("Eric","25","110","2");
I have tried:
mysql> alter table Students
-> NOCHECK CONSTRAINT CK_Years;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NOCHECK CONSTRAINT CK_Years' at line 2
I want to disable it just for this insert, and then bring it back (the check constraint).
As you can see, I got this error.
I tried to write it in couple ways. Wit 'CK_Years' or CK_Years or
`CK_Years`
got the same error for all of these ways.
I have verified that I have the constraint in the table:
mysql> select * from INFORMATION_SCHEMA.TABLE_CONSTRAINTS
-> where table_name='Students';
+--------------------+-------------------+-----------------+--------------+------------+-----------------+----------+
| CONSTRAINT_CATALOG | CONSTRAINT_SCHEMA | CONSTRAINT_NAME | TABLE_SCHEMA | TABLE_NAME | CONSTRAINT_TYPE | ENFORCED |
+--------------------+-------------------+-----------------+--------------+------------+-----------------+----------+
| def | School | PRIMARY | School | Students | PRIMARY KEY | YES |
| def | School | CK_Years | School | Students | CHECK | YES |
+--------------------+-------------------+-----------------+--------------+------------+-----------------+----------+
So how can I do it without changing the constraint or the fields in the insert statement?
How can I fix the syntax error?
And what is the reason for it?
Thanks.
MySQL does support syntax to alter a check constraint so it is not enforced, but it's different from the Microsoft SQL Server syntax.
mysql> alter table students alter check CK_Years NOT ENFORCED;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> insert into students values ('Eric',25,'110',2);
Query OK, 1 row affected (0.00 sec)
It's documented here: https://dev.mysql.com/doc/refman/8.0/en/alter-table.html
If you re-enable it, the constraint is enforced, and if you had inserted any rows that violate the constraint, you get an error trying to re-enable it.
mysql> alter table students alter check CK_Years ENFORCED;
ERROR 3819 (HY000): Check constraint 'CK_Years' is violated.
Also once you make the constraint not enforced, it would take effect for all clients, not just for one INSERT.
So I don't think you can do what you intend with a CHECK constraint. You may have to write a trigger that enforces a similar condition on that column, but has logic to enforce it conditionally.
Or do what most developers did before MySQL supported CHECK constraints: enforce it in the client app, before doing the INSERT. Then you can apply any conditions you want.
Is there any option (or even DB client) to require a confirmation when deleting a row for CASCADE deletes. For example:
DELETE FROM catalogs WHERE id=1
Warning: this will also DELETE CASCADE 92,358 products and 142 catalog_histories. Are you sure? (If so, temporarily turn on ALLOW_CASCADE_DELETES or add WITH CASCADES to query)
I will prefer a solution that doesn't require following particular rules in db schema and works with MySQL. (Alternatively if there is a way to force FK deletes while leaving CASCADE off schema in general then this will also be a good option.)
You can't do that in mysql
i tried it a bit https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=b6575f084b486025a66f6d52a4df9893
but the foreign key restaont has to be enable before you start to delete the row like in the example
So you must run two codes one with SET FOREIGN_KEY_CHECKS
CREATE TABLE catalogs(id int PRIMARY KEY);
INSERT INTO catalogs VALUES (1),(2);
CREATE TABLE catalogs_sub(id int, cat_id int,
FOREIGN KEY (cat_id)
REFERENCES catalogs( id)
ON DELETE CASCADE
)
INSERT INTO catalogs_sub VALUES (1,1),(2,1),(3,2),(4,2)
SELECT * FROM catalogs_sub
id | cat_id
-: | -----:
1 | 1
2 | 1
3 | 2
4 | 2
SET FOREIGN_KEY_CHECKS=0;
DELETE FROM catalogs WHERE id=1;
SET FOREIGN_KEY_CHECKS=1;
SELECT * FROM catalogs
| id |
| -: |
| 2 |
SELECT * FROM catalogs_sub
id | cat_id
-: | -----:
1 | 1
2 | 1
3 | 2
4 | 2
DELETE FROM catalogs WHERE id=2;
SELECT * FROM catalogs
| id |
| -: |
SELECT * FROM catalogs_sub
id | cat_id
-: | -----:
1 | 1
2 | 1
db<>fiddle here
On a simple table insert MYSQL constnatly fails on the 581st row and throws the following error:
INSERT interface (interface,status,description,deviceID) VALUES("Et34-10G","down","nodesc","1977")
INSERT interface (interface,status,description,deviceID) VALUES("Et35-10G","down","nodesc","1977")
INSERT interface (interface,status,description,deviceID) VALUES("Et36-10G","down","nodesc","1977")
INSERT interface (interface,status,description,deviceID) VALUES("Et37-10G","up","chic-02","1977")
INSERT interface (interface,status,description,deviceID) VALUES("Et38-10G","up","chic-06","1977")
INSERT interface (interface,status,description,deviceID) VALUES("Et39-10G","up","chic-07","1977")
DBD::mysql::db do failed: Cannot add or update a child row: a foreign key constraint fails (`dcss`.`interface`, CONSTRAINT `deviceID` FOREIGN KEY (`id`) REFERENCES `device` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION) at ./import_intstate_into_dcssdb.pl line 27.
It always fails on inserting the 581th row.
| 576 | Et34-10G | down | nodesc | 1977 |
| 577 | Et35-10G | down | nodesc | 1977 |
| 578 | Et36-10G | down | nodesc | 1977 |
| 579 | Et37-10G | up | chic-02 | 1977 |
| 580 | Et38-10G | up | chic-06 | 1977 |
+-----+--------------+--------+-------------------------------------------------------------------------
580 rows in set (0.00 sec)
I cannot understand why it was able to insert the previous rows with the same deviceID (1977) but throws at error consistently on the 581st row.
I have tested this and gotten the same results piping in the raw SQL statements.
-bash-4.1$ mysql -u root -p dcss < test.sql
Enter password:
ERROR 1452 (23000) at line 581: Cannot add or update a child row: a foreign key constraint fails (`dcss`.`interface`, CONSTRAINT `deviceID` FOREIGN KEY (`id`) REFERENCES `device` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION)
I am at a loss to explain this. The parent table has this id in it so there is not reason it should be failing on a constraint issue.
mysql> SELECT * FROM device WHERE id=1977;
+------+-------------------------+---------------+------------------+--------------+--------+--------+--------------+---------------+------+-------+
| id | fqdn | ipv4addr | ipv6addr | datacenterID | typeID | make | model | serial_number | os | shell |
+------+-------------------------+---------------+------------------+--------------+--------+--------+--------------+---------------+------+-------+
| 1977 | ls03.router | 10.10.255.210 | unk | 1 | 2 | ARISTA | DCS-7050S-64 | 1234567 | EOS | unk |
+------+-------------------------+---------------+------------------+--------------+--------+--------+--------------+---------------+------+-------+
1 row in set (0.00 sec)
Mate, can you look closer at the data that you try to insert as row 581?
I guess there is some special symbol there that is preventing the correct way to cast the string "1977" to integer 1977.
Try to insert it like that:
INSERT interface (interface,status,description,deviceID) VALUES("Et39-10G","up","chic-07", 1977);
Tell me how this is working for you.
I am trying to use ON DELETE CASCADE for a database I'm working on. Didn't seem to work so I tested it out on a simple example with no success.
CREATE TABLE foo (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
data VARCHAR(10),
PRIMARY KEY (id)
)ENGINE=InnoDB;
CREATE TABLE foo2 (
id INT UNSIGNED NOT NULL,
data2 VARCHAR(10),
PRIMARY KEY (id),
CONSTRAINT fk_foo2_id FOREIGN KEY (id) REFERENCES foo(id) ON DELETE CASCADE
)ENGINE=InnoDB;
INSERT INTO foo (data) VALUE ('hello'),('world'),('mysql');
INSERT INTO foo2 (data2) VALUE ('hello2'),('world2'),('mysql2');
SELECT * FROM foo;
+----+-------+
| id | data |
+----+-------+
| 1 | hello |
| 2 | world |
| 3 | mysql |
+----+-------+
3 rows in set (0.00 sec)
SELECT * FROM foo2;
+----+--------+
| id | data2 |
+----+--------+
| 1 | hello2 |
| 2 | world2 |
| 3 | mysql2 |
+----+--------+
3 rows in set (0.00 sec)
DELETE FROM foo WHERE id=2;
SELECT * FROM foo;
+----+-------+
| id | data |
+----+-------+
| 1 | hello |
| 3 | mysql |
+----+-------+
2 rows in set (0.00 sec)
SELECT * FROM foo2;
+----+--------+
| id | data2 |
+----+--------+
| 1 | hello2 |
| 2 | world2 |
| 3 | mysql2 |
+----+--------+
3 rows in set (0.00 sec)
I can't for the life of me figure out why this isn't working. I looked at similar questions and answers on here and I did exactly what they said and it still didn't work. Most of them just said to change to ENGINE=InnoDb, but I tried it and no success.
There must be something I'm missing here, and it's probably very obvious.. Monday mornings.
If anyone can shed some light on this little noob problem of mine, I would greatly appreciate it!
Edit: removed the auto_increment from id in foo2 as it did not belong there
The first thing that pops to mind is to check the setting of the foreign_key_checks variable. If that's set to 0 (FALSE), then foreign key constraints are NOT enforced.
SHOW VARIABLES LIKE 'foreign_key_checks'
To enable foeign key constraints, set to the variable to 1
SET foreign_key_checks = 1;
NOTE: this affects only the current session. New sessions inherit the GLOBAL setting.
Also, verify that your tables are actually using the InnoDB engine, and that the foreign keys are defined. Easiest way is to get the output from:
SHOW CREATE TABLE foo;
SHOW CREATE TABLE foo2;
FOLLOWUP
This is something that we expect NOT to be broken in MySQL 5.1.61.
As a workaround, try defining the foreign key constraint as a separate ALTER TABLE statement.
ALTER TABLE foo2
ADD CONSTRAINT fk_foo2_id FOREIGN KEY (id) REFERENCES foo(id) ON DELETE CASCADE ;
I don't see much use in a foreign key constraint between two columns that are both defined with "auto_increment". In your example, you could easily create several rows in table "foo" (without a counterpart in "foo2"), and from then onwards you could not control whether "id" values in both tables match.
I admit I didn't check the documentation, but it would not surprise me if MySQL silently ignored a foreign key constraint for an auto-generated column.
IMNSHO, your table "foo2" should use "id" values which are set explicitly and reference specific rows in "foo", because then it would make sense that deleting such "foo" rows should cascade onto "foo2".
I want to add a second foreign key constraint between data and containers. When I delete a container, the data linked to this container has to be deleted too.
The tables:
mysql> DESCRIBE data;
+------------------------+--------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------------+--------------+------+-----+---------------------+----------------
| imei | varchar(15) | NO | MUL | NULL |
mysql> DESCRIBE containers;
+--------------------+-------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+-------------+------+-----+---------------------+----------------+
| imei | varchar(15) | NO | MUL | NULL | |
I create a foreign key with this statement:
mysql> ALTER TABLE `data` ADD FOREIGN KEY (`imei`) REFERENCES `containers`(`imei`) ON DELETE CASCADE;
Query OK, 15168 rows affected (0.12 sec)
Records: 15168 Duplicates: 0 Warnings: 0
But the foreign key hasn't been created:
mysql> use INFORMATION_SCHEMA;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select TABLE_NAME,COLUMN_NAME,CONSTRAINT_NAME, REFERENCED_TABLE_NAME,REFERENCED_COLUMN_NAME from KEY_COLUMN_USAGE where REFERENCED_TABLE_NAME = 'containers';
+----------------+-------------+-----------------------+-----------------------+------------------------+
| TABLE_NAME | COLUMN_NAME | CONSTRAINT_NAME | REFERENCED_TABLE_NAME | REFERENCED_COLUMN_NAME |
+----------------+-------------+-----------------------+-----------------------+------------------------+
| container_logs | imei | container_logs_ibfk_1 | containers | imei |
+----------------+-------------+-----------------------+-----------------------+------------------------+
1 row in set (0.16 sec)
What am I doing wrong?
Not all storage engines support foreign keys; storage engines that does not support certain SQL features however do not generate error, but just ignore the statements (actually the SQL parser is higher layer in the MySQL architecture, which uses lower-level APIs to communicate with the storage engines).
So if you are using MyISAM, you cannot create a foreign key, but no error will be returned