ON DELETE CASCADE not working in MySQL - php

I am using the following SQL to create a table named app_info:
CREATE TABLE IF NOT EXISTS `app_info` (
`_id` int(11) NOT NULL AUTO_INCREMENT,
`app_name` varchar(50) DEFAULT NULL,
`app_owner` varchar(50) DEFAULT NULL,
`last_update` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;
I am using the following SQL to create a table named tab_info:
CREATE TABLE `myDB`.`tab_info` (
`_id` INT NOT NULL AUTO_INCREMENT ,
`app_id` INT NOT NULL ,
`tab_title` VARCHAR(15) NOT NULL ,
PRIMARY KEY (`_id`) ,
UNIQUE INDEX `app_id_UNIQUE` (`app_id` ASC) ,
INDEX `app_tab_key` (`app_id` ASC) ,
CONSTRAINT `app_tab_key`
FOREIGN KEY (`app_id` )
REFERENCES `myDB`.`app_info` (`_id` )
ON DELETE CASCADE
ON UPDATE CASCADE);
But when I delete data from primary key table, the orphaned rows in the foreign key table are not being deleted automatically. Does anyone know what the problem could be?

The MyISAM storage engine doesn't support foreign key constraints. The constraint is parsed but silently ignored.
To fix your problem use the InnoDB engine instead (for both tables).
CREATE TABLE ( ... ) ENGINE = InnoDB ... ;
Instead of dropping your tables and recreating them you can also change the storage engine:
ALTER TABLE myDB.app_info ENGINE = InnoDB;
ALTER TABLE myDB.tab_info ENGINE = InnoDB;
After changing the engine you will need to add the foreign key constraint again.

Related

I have the following code for referencing but it doesn't work [duplicate]

When I execute the follow two queries (I have stripped them down to absolutely necessary):
mysql> CREATE TABLE foo(id INT PRIMARY KEY);
Query OK, 0 rows affected (0.01 sec)
mysql> CREATE TABLE bar ( id INT, ref INT, FOREIGN KEY (ref) REFERENCES foo(id)) ENGINE InnoDB;
I get the following error:
ERROR 1005 (HY000): Can't create table './test/bar.frm' (errno: 150)
Where the **** is my error? I haven't found him while staring at this for half an hour.
From FOREIGN KEY Constraints
If you re-create a table that was
dropped, it must have a definition
that conforms to the foreign key
constraints referencing it. It must
have the right column names and types,
and it must have indexes on the
referenced keys, as stated earlier. If
these are not satisfied, MySQL returns
error number 1005 and refers to error
150 in the error message.
My suspicion is that it's because you didn't create foo as InnoDB, as everything else looks OK.
Edit: from the same page -
Both tables must be InnoDB tables and they must not be TEMPORARY tables.
You can use the command SHOW ENGINE INNODB STATUS to get more specific information about the error.
It will give you a result with a Status column containing a lot of text.
Look for the section called LATEST FOREIGN KEY ERROR which could for example look like this:
------------------------
LATEST FOREIGN KEY ERROR
------------------------
190215 11:51:26 Error in foreign key constraint of table `mydb1`.`contacts`:
Create table `mydb1`.`contacts` with foreign key constraint failed. You have defined a SET NULL condition but column 'domain_id' is defined as NOT NULL in ' FOREIGN KEY (domain_id) REFERENCES domains (id) ON DELETE SET NULL ON UPDATE CASCADE,
CONSTRAINT contacts_teams_id_fk FOREIGN KEY (team_id) REFERENCES teams (id) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT' near ' ON DELETE SET NULL ON UPDATE CASCADE,
CONSTRAINT contacts_teams_id_fk FOREIGN KEY (team_id) REFERENCES teams (id) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT'.
To create a foreign key ,
both the main column and the reference column must have same definition.
both tables engine must be InnoDB.
You can alter the engine of table using this command , please take the backup before executing this command.
alter table [table name] ENGINE=InnoDB;
I had the same problem, for those who are having this also:
check the table name of the referenced table
I had forgotten the 's' at the end of my table name
eg table Client --> Clients
:)
Apart form many other reasons to end up with MySql Error 150 (while using InnoDB), One of the probable reason, is the undefined KEY in the create statement of the table containing the column name referenced as a foreign key in the relative table.
Let's say the create statement of master table is -
CREATE TABLE 'master_table' (
'id' int(10) NOT NULL AUTO_INCREMENT,
'record_id' char(10) NOT NULL,
'name' varchar(50) NOT NULL DEFAULT '',
'address' varchar(200) NOT NULL DEFAULT '',
PRIMARY KEY ('id')
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
and the create syntax for the relative_table table where the foreign key constraint is set from primary table -
CREATE TABLE 'relative_table' (
'id' int(10) NOT NULL AUTO_INCREMENT,
'salary' int(10) NOT NULL DEFAULT '',
'grade' char(2) NOT NULL DEFAULT '',
'record_id' char(10) DEFAULT NULL,
PRIMARY KEY ('id'),
CONSTRAINT 'fk_slave_master' FOREIGN KEY ('record_id') REFERENCES 'master' ('record_id')
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
This script is definitely going to end with MySql Error 150 if using InnoDB.
To solve this, we need to add a KEY for the The column record_id in the master_table table and then reference in the relative_table table to be used as a foreign_key.
Finally, the create statement for the master_table, will be -
CREATE TABLE 'master_table' (
'id' int(10) NOT NULL AUTO_INCREMENT,
'record_id' char(10) NOT NULL,
'name' varchar(50) NOT NULL DEFAULT '',
'address' varchar(200) NOT NULL DEFAULT '',
PRIMARY KEY ('id'),
KEY 'record_id' ('record_id')
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
I had very same problem and the reason was the "collation" of columns was different. One was latin1 while the other was utf8
This may also happen if you have not given correct column name after "references" keyword.

SQL dump to table like in phpmyadmin

I am developing a backup/restore app in yii. I need a mysql command to dump a table like phpmyadmin does, it does not wrap the foreign keys inside table definition, but put is as "ALTER TABLE" command.
--
-- Table structure for table `sales_detail`
--
CREATE TABLE IF NOT EXISTS `sales_detail` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`salesFk` int(11) NOT NULL,
`productFk` int(11) NOT NULL,
`quantity` decimal(15,3) NOT NULL,
`unitPrice` decimal(15,3) NOT NULL,
`comUnitPrice` decimal(15,3) NOT NULL DEFAULT '0.000',
`minUnitPrice` decimal(15,3) NOT NULL DEFAULT '0.000',
PRIMARY KEY (`id`),
KEY `productFk` (`productFk`),
KEY `salesFk` (`salesFk`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=378 ;
--
-- Constraints for dumped tables
--
--
-- Constraints for table `sales_detail`
--
ALTER TABLE `sales_detail`
ADD CONSTRAINT `sales_detail_ibfk_1` FOREIGN KEY (`productFk`) REFERENCES `product` (`id`) ON UPDATE CASCADE,
ADD CONSTRAINT `sales_detail_ibfk_2` FOREIGN KEY (`salesFk`) REFERENCES `sales` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
Thanks in advance

Foreign Key constraints in MySQL

I am a newbie to PHP. I have been given the code snippet below as homework:
CREATE TABLE `admin_log` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`statusdate` DATETIME DEFAULT NULL,
`type` INT(11) DEFAULT NULL
PRIMARY KEY (`id`)
) ENGINE=MYISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin
Why will it not be possible to set up any foreign key constraints using this table?
I have done some research on Google and I cant find a reason why foreign key constraints are not possible. Please help
You can do that like this :
CREATE TABLE `admin_log` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`statusdate` DATETIME DEFAULT NULL,
`type` INT(11) DEFAULT NULL,
INDEX (type),
FOREIGN KEY (type)
REFERENCES type(id)
ON UPDATE CASCADE ON DELETE RESTRICT,
PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=latin
Notice the engine INNODB insetad of MYISAM which doesn't permit foreign key.
Or using MySQLAdmin in the "structure" tab, click on the "relationals view" link below the table description.
Even it has been mentioned on comment before -- just to make it more prominent: MyISAM is not supporting foreign keys. So you will need to change the engine of your table to e.g. INNODB if possible.

Cannot create table errno : 150 on Mysql

i get another errno 150 on mysql. i already look at table engine, column type, but no luck, its nothing wrong in my view.
where im going wrong this time?
i get error when creating tag table that relate to image_tag and tag_lang.
-- -----------------------------------------------------
-- Table `ratna`.`image_tag`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `ratna`.`image_tag` ;
CREATE TABLE IF NOT EXISTS `ratna`.`image_tag` (
`id` INT(11) NOT NULL ,
`tag` INT(11) NOT NULL ,
PRIMARY KEY (`id`, `tag`) ,
INDEX `image_fk` (`id` ASC) ,
CONSTRAINT `image_fk`
FOREIGN KEY (`id` )
REFERENCES `ratna`.`image` (`id` )
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;
-- -----------------------------------------------------
-- Table `ratna`.`tag_lang`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `ratna`.`tag_lang` ;
CREATE TABLE IF NOT EXISTS `ratna`.`tag_lang` (
`id` INT(11) NOT NULL ,
`lang` INT(20) NOT NULL ,
`tag_desc` VARCHAR(200) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci' NOT NULL ,
PRIMARY KEY (`id`, `lang`) )
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_general_ci;
-- -----------------------------------------------------
-- Table `ratna`.`tag`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `ratna`.`tag` ;
CREATE TABLE IF NOT EXISTS `ratna`.`tag` (
`id` INT(11) NOT NULL AUTO_INCREMENT ,
`name` VARCHAR(50) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci' NOT NULL ,
`seq` INT(11) NOT NULL ,
PRIMARY KEY (`id`) ,
INDEX `image_tag_fk` (`id` ASC) ,
INDEX `tag_lang` (`id` ASC) ,
CONSTRAINT `image_tag_fk`
FOREIGN KEY (`id` )
REFERENCES `ratna`.`image_tag` (`tag` )
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT `tag_lang`
FOREIGN KEY (`id` )
REFERENCES `ratna`.`tag_lang` (`id` )
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB
AUTO_INCREMENT = 13
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_general_ci;
This:
REFERENCES `ratna`.`image_tag` (`tag` )
is not valid, because image_tag does not have any index that begins with tag. As explained in the documentation:
InnoDB permits a foreign key to reference any index column or group of columns. However, in the referenced table, there must be an index where the referenced columns are listed as the first columns in the same order.
("The referenced table" in this case is image_tag, and "the referenced columns" are just tag.)
First google result for mysql error 150 shows:
If you re-create a table that was dropped, it must have a definition that conforms to the foreign key constraints referencing it. It must have the right column names and types, and it must have indexes on the referenced keys, as stated earlier. If these are not satisfied, MySQL returns error number 1005 and refers to error 150 in the error message.
If MySQL reports an error number 1005 from a CREATE TABLE statement, and the error message refers to error 150, table creation failed because a foreign key constraint was not correctly formed. Similarly, if an ALTER TABLE fails and it refers to error 150, that means a foreign key definition would be incorrectly formed for the altered table. You can use SHOW ENGINE INNODB STATUS to display a detailed explanation of the most recent InnoDB foreign key error in the server.
http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
in my case it was issue of
foreign key (table_column_name_in_smaller_case) references
primary_key_table_in_upper_case (table_column_name_in_smaller_case)
since my primary key table is in Lower case, i changed this upper foreign key reference from
*primary_key_table_in_upper_case*
to
*primary_key_table_in_lower_case*
and it worked

SQL Syntax Error (phpMyAdmin)

What's wrong with this SQL statement:
ALTER TABLE `tbl_issue`
ADD CONSTRAINT `FK_issue_requester`
FOREIGN KEY (`requester_id`) REFERENCES `tbl_user` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT;
I have tables called tbl_issue and tbl_user within a database called trackstar_dev.
phpMyAdmin said:
#1005 - Can't create table 'trackstar_dev.#sql-1a4_9d' (errno: 121) (Details...)
The most common reason for this error is that the foreign key constraint have the same name as in another table. Foreign keys' names must be unique in the database (not just on table level). Do you have requester_id in another table in your database?
you will get this message if you're trying to add a constraint with a name that's already used somewhere else, c you will get this message if you're trying to add a constraint with a name that's already used somewhere else . change it and it will be ok :)
I had this same problem. Drop all the tables in your database and then use the SQL code below to recreate them. I assume you are following the example in the agile web development with Yii 1.1 and php 5
- Disable foreign keys
SET FOREIGN_KEY_CHECKS = 0 ;# MySQL returned an empty result set (i.e. zero rows).
-- Create tables section -------------------------------------------------
-- Table tbl_project
CREATE TABLE IF NOT EXISTS `tbl_project` (
`id` INTEGER NOT NULL auto_increment,
`name` varchar(128) NOT NULL,
`description` text NOT NULL,
`create_time` DATETIME default NULL,
`create_user_id` INTEGER default NULL,
`update_time` DATETIME default NULL,
`update_user_id` INTEGER default NULL,
PRIMARY KEY (`id`)
) ENGINE = InnoDB
;# MySQL returned an empty result set (i.e. zero rows).
-- DROP TABLE IF EXISTS `tbl_issue` ;
CREATE TABLE IF NOT EXISTS `tbl_issue`
(
`id` INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
`name` varchar(256) NOT NULL,
`description` varchar(2000),
`project_id` INTEGER,
`type_id` INTEGER,
`status_id` INTEGER,
`owner_id` INTEGER,
`requester_id` INTEGER,
`create_time` DATETIME,
`create_user_id` INTEGER,
`update_time` DATETIME,
`update_user_id` INTEGER
) ENGINE = InnoDB
;# MySQL returned an empty result set (i.e. zero rows).
-- DROP TABLE IF EXISTS `tbl_user` ;
-- Table User
CREATE TABLE IF NOT EXISTS `tbl_user`
(
`id` INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
`email` Varchar(256) NOT NULL,
`username` Varchar(256),
`password` Varchar(256),
`last_login_time` Datetime,
`create_time` DATETIME,
`create_user_id` INTEGER,
`update_time` DATETIME,
`update_user_id` INTEGER
) ENGINE = InnoDB
;# MySQL returned an empty result set (i.e. zero rows).
-- DROP TABLE IF EXISTS `tbl_project_user_assignment` ;
-- Table User
CREATE TABLE IF NOT EXISTS `tbl_project_user_assignment`
(
`project_id` Int(11) NOT NULL,
`user_id` Int(11) NOT NULL,
`create_time` DATETIME,
`create_user_id` INTEGER,
`update_time` DATETIME,
`update_user_id` INTEGER,
PRIMARY KEY (`project_id`,`user_id`)
) ENGINE = InnoDB
;# MySQL returned an empty result set (i.e. zero rows).
-- The Relationships
ALTER TABLE `tbl_issue` ADD CONSTRAINT `FK_issue_project` FOREIGN KEY (`project_id`) REFERENCES `tbl_project` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT;# MySQL returned an empty result set (i.e. zero rows).
ALTER TABLE `tbl_issue` ADD CONSTRAINT `FK_issue_owner` FOREIGN KEY (`owner_id`) REFERENCES `tbl_user` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT;# MySQL returned an empty result set (i.e. zero rows).
ALTER TABLE `tbl_issue` ADD CONSTRAINT `FK_issue_requester` FOREIGN KEY (`requester_id`) REFERENCES `tbl_user` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT;# MySQL returned an empty result set (i.e. zero rows).
ALTER TABLE `tbl_project_user_assignment` ADD CONSTRAINT `FK_project_user` FOREIGN KEY (`project_id`) REFERENCES `tbl_project` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT;# MySQL returned an empty result set (i.e. zero rows).
ALTER TABLE `tbl_project_user_assignment` ADD CONSTRAINT `FK_user_project` FOREIGN KEY (`user_id`) REFERENCES `tbl_user` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT;# MySQL returned an empty result set (i.e. zero rows).
-- Insert some seed data so we can just begin using the database
INSERT INTO `tbl_user`
(`email`, `username`, `password`)
VALUES
('test1#notanaddress.com','Test_User_One', MD5('test1')),
('test2#notanaddress.com','Test_User_Two', MD5('test2'))
;# 2 rows affected.
-- Enable foreign keys
SET FOREIGN_KEY_CHECKS = 1 ;# MySQL returned an empty result set (i.e. zero rows).

Categories