How to delete two linked rows from MySQL database? - mysql

Can somebody show my how to delete two linked rows?
I use Delphi 2007 and MySQL.
I have a database with two tables:
CREATE TABLE `Picture`.`Picture` (
`ID` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
`IMG` LONGBLOB,
PRIMARY KEY (`ID`)
)
ENGINE = InnoDB;
CREATE TABLE `contacts` (
`ID` int(10) unsigned NOT NULL auto_increment,
`FirstName` varchar(45) NOT NULL,
`LastName` varchar(45) NOT NULL,
`Phone` varchar(45) default NULL,
`PICID` int(10) unsigned default NULL,
PRIMARY KEY (`ID`),
KEY `FK_contacts_1` (`PICID`),
CONSTRAINT `FK_contacts_1` FOREIGN KEY (`PICID`) REFERENCES `picture` (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
In my Delphi Application I have Delete button. When I find some contact on my DBGrid and press Delete button I can delete only contact from table contacts, I also want to delete contact picture.
I want to delete row from table contacts and row from table Picture. Table Picture is linked to table contacts with foreign key.

Use FK with ON DELETE CASCADE - http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
When you delete a row from the master table Picture SQL engine cascades to detail table and deletes there too.

Related

Should I use Inner Join in this case?

I am working on a student attendance mini-project, and I don't know how to proceed for my database. I'm new to SQL and databases in general so this might seem dumb to you.
So, I want to do a database containing the table student, which contains : student_id (primary key) , name (string) and attendance(boolean) (that's the bare minimum, i'll add more afterwards) and I want to register the daily attendance of the students. So I want to have all the students tied to every date of the week.
I created a date table in phpMyadmin but I don't know how to proceed to link them, i've tried an Inner Join and it was successful.
The problem is : If i want to add another line to the student table my table won't update, so is there a way to "automatically" tie all the students to the date table ?
Sorry if this seems confused I've tried my best to summarize it !
Lets have some idea about tables should be there to implement a proper Student Attendance system in place. I have copied create script for some of my tables that used for maintaining Students record per course. I hope following sample Table scripts with relation will help you understanding regarding table structure and also to solve your issue.
Please be noted, That this table structures for your your reference only. You can add/remove tables/columns as per your requirement once you get an overall idea from this post.
CREATE TABLE `staff` (
`id` int(11) NOT NULL,
`type` varchar(200) DEFAULT NULL,
`first_name` varchar(200) DEFAULT NULL,
`last_name` varchar(200) DEFAULT NULL,
`emal` varchar(200) DEFAULT NULL,
`contact` varchar(200) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `batch` (
`id` int(11) NOT NULL,
`department` varchar(200) DEFAULT NULL,
`details` varchar(200) DEFAULT NULL,
`staff_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `batch_staff_idx` (`staff_id`),
CONSTRAINT `batch_staff` FOREIGN KEY (`staff_id`) REFERENCES `staff` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `student` (
`id` int(11) NOT NULL,
`batch_id` int(11) DEFAULT NULL,
`first_name` varchar(200) DEFAULT NULL,
`last_name` varchar(200) DEFAULT NULL,
`email` varchar(200) DEFAULT NULL,
`contact` varchar(200) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `batch_student_idx` (`batch_id`),
CONSTRAINT `batch_student` FOREIGN KEY (`batch_id`) REFERENCES `batch` (`batch_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `course` (
`id` int(11) NOT NULL,
`name` varchar(200) DEFAULT NULL,
`details` varchar(200) DEFAULT NULL,
`staff_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `course_staff_idx` (`staff_id`),
CONSTRAINT `course_staff` FOREIGN KEY (`staff_id`) REFERENCES `staff` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `attendence` (
`course_id` int(11) NOT NULL,
`student_id` int(11) DEFAULT NULL,
`class_date` date DEFAULT NULL,
KEY `att_course_idx` (`course_id`),
KEY `att_student_idx` (`student_id`),
CONSTRAINT `att_course` FOREIGN KEY (`course_id`) REFERENCES `course` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `att_student` FOREIGN KEY (`student_id`) REFERENCES `student` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Your required data will finally store into table Attendance. From this table data, you will be able to find list of students absent/present per date and per course. Remember, the attendance table should enrich daily from a automated OR a manual process.

Mysql Foreign Key constraint fails to create with unexisting constraint

So I have two tables, customers and appointments.
Im trying to create a very simple FK relation between appointments.customer_id and customers.id, however when I do my ALTER TABLE trying to add the FK im getting this error:
MySQL said: Cannot add or update a child row: a foreign key constraint fails (wax.#sql-2c5_100, CONSTRAINT customer_fk FOREIGN KEY (id) REFERENCES customers (id) ON DELETE CASCADE ON UPDATE CASCADE)
This constraint "#sql-2c5_100" seems to be some randomly generated constraint, that I can not find ANYWHERE. I've looked on every table on the database, ive looked on all the tables on the information schema and it simply does not exist.
Thanks!
Edit:
Here's the create table outputs
CREATE TABLE `appointments` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`customer_id` int(11) unsigned NOT NULL,
`name` varchar(255) DEFAULT NULL
PRIMARY KEY (`id`),
KEY `customer_id` (`customer_id`)
) ENGINE=InnoDB AUTO_INCREMENT=290958 DEFAULT CHARSET=utf8;
CREATE TABLE `customers` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`first_name` varchar(255) NOT NULL DEFAULT '',
`last_name` varchar(255) NOT NULL DEFAULT '',
`phone` varchar(20) DEFAULT NULL
PRIMARY KEY (`id`),
KEY `sf_id` (`sf_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

MySQL Not allowing delete even though FK relationship ON DELETE CASCADE set

I am working on a project that makes use of a MySQL Database to store snippets of code for use on multiple websites. For each content snippet I also keep an edit history table, to which I add a record every time a snippet is updated. Occasionally it will be desirable to delete a snippet completely, and any associated edit history. When setting up the DB, I set up the foreign key relationship to ON DELETE CASCADE so that deleting the snippet will automatically delete the history. However, I am getting the following error:
Error in query: delete from SNIPPET where id = 1. Cannot delete or update a parent row: a foreign key constraint fails (universal_content_repository/SNIPPET_EDIT_HISTORY, CONSTRAINT fk_SNIPPET_EDIT_HISTORYRelationship13 FOREIGN KEY (snippet_id) REFERENCES SNIPPET (id))
Here is the code I use to create the DB as well as the relationships:
/*Schema universal_content_repository*/
CREATE SCHEMA IF NOT EXISTS `universal_content_repository`
DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
USE `universal_content_repository`;
CREATE TABLE `universal_content_repository`.`USER` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'Stores the ID for the User.',
`username` VARCHAR(20) NOT NULL,
`first_name` VARCHAR(32) NOT NULL,
`last_name` VARCHAR(32) NOT NULL,
`is_active` VARCHAR(5) NOT NULL DEFAULT true,
`password` VARCHAR(32) NOT NULL,
`is_admin` BIT NOT NULL DEFAULT 0,
`prefers_wysiwyg` BIT DEFAULT 0,
PRIMARY KEY (`id`)
) COMMENT 'Stores information about all Users for the Universal Content Repository.' ENGINE=INNODB
ROW_FORMAT=DEFAULT;
CREATE TABLE `universal_content_repository`.`SNIPPET` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`title` VARCHAR(255) NOT NULL,
`content` TEXT NOT NULL,
`created_by` INT UNSIGNED,
`wysiwyg_editable` VARCHAR(6) NOT NULL DEFAULT true,
`is_enabled` BIT NOT NULL DEFAULT 1,
PRIMARY KEY (`id`)
) COMMENT 'Guarantees that no two snippets may have the same name or ID.' ENGINE=INNODB
ROW_FORMAT=DEFAULT;
CREATE TABLE `universal_content_repository`.`IMAGE` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(32) NOT NULL,
`url` TEXT NOT NULL,
`alt` VARCHAR(32),
PRIMARY KEY (`id`)
) ENGINE=INNODB
ROW_FORMAT=DEFAULT;
CREATE TABLE `universal_content_repository`.`IMAGE_IN_SNIPPET` (
`rel_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`snippet_id` INT UNSIGNED,
`image_id` INT UNSIGNED,
`position` INT COMMENT 'Stores the position of the image within the snippet, as notated in the snippet as [index]',
PRIMARY KEY (`rel_id`)
) ENGINE=INNODB
ROW_FORMAT=DEFAULT;
CREATE TABLE `universal_content_repository`.`SNIPPET_EDIT_HISTORY` (
`revision_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`editing_user` INT UNSIGNED,
`snippet_id` INT UNSIGNED,
`old_contents` TEXT NOT NULL COMMENT 'Stores the old contents of the snippet.',
`edit_date` DATETIME NOT NULL COMMENT 'Stores the DateTime of the edit.',
PRIMARY KEY (`revision_id`)
) ENGINE=INNODB
ROW_FORMAT=DEFAULT;
CREATE TABLE `universal_content_repository`.`SESSION` (
`id` VARCHAR(32) NOT NULL COMMENT 'Stores the Session ID',
`access` INT(10) UNSIGNED NOT NULL,
`data` TEXT,
PRIMARY KEY (`id`)
) ENGINE=INNODB
ROW_FORMAT=DEFAULT;
ALTER TABLE `universal_content_repository`.`USER` ADD UNIQUE `Identifiers` (`id`,`username`);
ALTER TABLE `universal_content_repository`.`SNIPPET` ADD UNIQUE `identifiers` (`title`,`id`);
ALTER TABLE `universal_content_repository`.`SNIPPET` ADD CONSTRAINT `fk_SNIPPETRelationship8` FOREIGN KEY (`created_by`) REFERENCES `universal_content_repository`.`USER`(`id`) MATCH SIMPLE ON UPDATE RESTRICT ON DELETE RESTRICT;
ALTER TABLE `universal_content_repository`.`IMAGE_IN_SNIPPET` ADD CONSTRAINT `fk_IMAGE_IN_SNIPPETRelationship10` FOREIGN KEY (`snippet_id`) REFERENCES `universal_content_repository`.`SNIPPET`(`id`) MATCH SIMPLE ON UPDATE CASCADE ON DELETE CASCADE;
ALTER TABLE `universal_content_repository`.`IMAGE_IN_SNIPPET` ADD CONSTRAINT `fk_IMAGE_IN_SNIPPETRelationship11` FOREIGN KEY (`image_id`) REFERENCES `universal_content_repository`.`IMAGE`(`id`) MATCH SIMPLE ON UPDATE RESTRICT ON DELETE RESTRICT;
ALTER TABLE `universal_content_repository`.`SNIPPET_EDIT_HISTORY` ADD CONSTRAINT `fk_SNIPPET_EDIT_HISTORYRelationship12` FOREIGN KEY (`editing_user`) REFERENCES `universal_content_repository`.`USER`(`id`) MATCH SIMPLE ON UPDATE RESTRICT ON DELETE RESTRICT;
ALTER TABLE `universal_content_repository`.`SNIPPET_EDIT_HISTORY` ADD CONSTRAINT `fk_SNIPPET_EDIT_HISTORYRelationship13` FOREIGN KEY (`snippet_id`) REFERENCES `universal_content_repository`.`SNIPPET`(`id`) MATCH SIMPLE ON UPDATE CASCADE ON DELETE CASCADE;
If you want to see a graphical representation of the DB, you can see it at SchemaBank.
For those without a SchemaBank account, here is the ER:
Any ideas?
Looks like your code is right.
If it's practical, dump that database and restore it onto a different server as a test. If INNODB and MySQL internal states have gotten out of sync, that should give you a well-behaved database on the server you restore to.

mysql prevent deleting records that is in used

i got 2 tables. product and order_items which contain all the products that were bought.
so how do i create a relationship in mysql whereby if a product exists in order_items, restrict users from deleting it from product table??
thanks
You can do this with Foreign keys with the InnoDB Engine.
ALTER TABLE order_items ADD FOREIGN KEY (`p_id`) REFERENCES `products` (`p_id`);
The ID on products must be a key (it probably already is the primary key).
If you are not using InnoDB, you cannot enforce this with MySQL, but it must be enforced with your application (check whether a record exists in orders first for example).
So with your tables, you run:
ALTER TABLE `order_item` ADD FOREIGN KEY (`bookid`) REFERENCES `book` (`id`);
You're looking for a foreign key. Specifically look at the "Restrict" option.
http://dev.mysql.com/doc/refman/5.1/en/innodb-foreign-key-constraints.html
my table structure:
CREATE TABLE `book` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`userid` int(11) NOT NULL,
`title` varchar(100) NOT NULL,
`description` text NOT NULL,
`author` varchar(100) NOT NULL,
`publisher` varchar(100) NOT NULL,
`edition` int(11) NOT NULL,
`isbn` varchar(13) NOT NULL,
`category` varchar(11) NOT NULL,
`datesubmitted` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARSET=utf8;
CREATE TABLE `order_item` (
`orderid` int(11) NOT NULL,
`bookid` int(11) NOT NULL,
KEY `Foreign` (`bookid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Help with my table structure

I'm trying to make an address book. And have made my tables like this:
CREATE TABLE `list_`.`contacts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` tinyint(11) NOT NULL,
`group` varchar(128) NOT NULL,
`first_name` varchar(128) NOT NULL,
`last_name` varchar(128) NOT NULL,
`address` varchar(128) NOT NULL,
`city` varchar(128) NOT NULL,
`state` varchar(2) NOT NULL,
`zip` int(5) NOT NULL,
`phone_number` varchar(16) NOT NULL,
`cell_number` varchar(16) NOT NULL,
`work_number` varchar(16) NOT NULL,
`fax_number` varchar(16) NOT NULL,
`email` varchar(128) NOT NULL,
`company` varchar(55) NOT NULL,
`title` varchar(56) NOT NULL,
`notes` text NOT NULL,
`date_added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`,`user_id`),
KEY `user_id` (`user_id`),
KEY `group` (`group`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 AUTO_INCREMENT=9 ;
CREATE TABLE `list_`.`groups` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` tinyint(11) NOT NULL,
`position` int(8) unsigned NOT NULL DEFAULT '0',
`name` varchar(128) NOT NULL,
`date_added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`,`user_id`),
KEY `user_id` (`user_id`),
KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8 AUTO_INCREMENT=32 ;
My logic here is that I have all the contacts in the contacts table, from there I have a column called group that I use to filter the contacts into groups.
Then I have a table called groups that I'll use to keep track of what groups where created by a specific user and fill a with these groups so they can move the contacts around.
When a group is deleted I will throw back an error no letting it be deleted if the group contains contacts. I can probably query the contacts to see what group they belong to and if they belong to the group being deleted then I'll move them into a group called Uncategorized or something.
But if they choose to accept and delete ALL contacts within a group then go ahead and delete the group and all child rows that belong to that group.
I am having trouble creating my Foreing Keys in the contacts table. No matter what combination of index and keys I try I still can't make it work.
--
-- Constraints for table `contacts`
--
ALTER TABLE `list_`.`contacts`
ADD CONSTRAINT `contacts_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`),
ADD CONSTRAINT `contacts_ibfk_2` FOREIGN KEY (`group`) REFERENCES `groups` (`name`) ON UPDATE CASCADE;
--
-- Constraints for table `groups`
--
ALTER TABLE `list_`.`groups`
ADD CONSTRAINT `group_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`);
Also, can someone help me with the ON DELETE and ON UPDATE. To help me figure out how I can delete all child rows that reference the name column in groups
I do not think you should have MySQL do so much heavy lifting, specifically deleting a group if it is empty. Is there any specific reason to do this, i.e. can the group no longer be used if it is empty? You could probably achieve this with mysql triggers if you really wanted to.
As for preventing the deletion of a group that is simply done by the foriegn key on contacts that you already have on groups. However I highly recommend that you use ids rather than names for keys.
What you are saying seems to conflict, however: you want to prevent deletion of a group that has contacts, but you want all contacts in a group to be deleted when the group is deleted?