When parent row link to child row - php

Example: I have category table with the FOREIGN KEY to the same table:
CREATE TABLE `categories` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(250) COLLATE utf8_unicode_ci NOT NULL,
`parent_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `categories_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `categories` (`id`)
)
How to constraint the parent_id that it can't be the child parent_id.
Example:
we have a parent's row where parent_id equal child's id:
['1', 'parent_name', '**2**']
Child row:
['2', 'child_name', '**1**']
How to fix this by MySQL?

It already does not happen during insert (base on the defination of the table), you have foreign key on parent_id to id your example is a paradox, but it may happen during update of the table so you need to create a trigger for Update to prevent updating the table such as the example also For this case The CHECK constraint does not work, as I mentioned one way is to use a trigger for before update:
CREATE TRIGGER trigger_categories
BEFORE Update
ON categories FOR EACH ROW
BEGIN
DECLARE msg VARCHAR(255);
IF EXISTS (select * from categories c where c.id=NEW.parent_id and c.parent_id=NEW.id) THEN
set msg = "DIE: you can not make a parent of chield as it's chield...";
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg;
// also you can make NEW as NULL for preventing update under mentioned condition
END IF;
END;

Related

Get the value when a MySQL constraint fails

Assuming I am inserting rows in a MySQL table with a constraint
CREATE TABLE `parent` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
)
ENGINE=InnoDB
;
CREATE TABLE `child` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`id_parent` INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (`id`),
INDEX `FK_parent_child` (`id_parent`),
CONSTRAINT `FK_parent_child` FOREIGN KEY (`id_parent`) REFERENCES `parent` (`id`),
)
ENGINE=InnoDB
;
Then when I do an insert in the child table without the entry in the parent table:
INSERT INTO child (id, id_parent) VALUES (1, 1);
I get the following error:
Cannot add or update a child row: a foreign key constraint fails (`...`.`child`, CONSTRAINT `FK_parent_child` FOREIGN KEY (`id_parent`) REFERENCES `parent` (`id`))`
But is there a way to retrieve the value of the insert-failed row, aka 1 here? Because when I insert thousands of rows at the same time, it would be very useful to get the failed one.
I would like a fully-MySQL way, but a PHP way would work too in my case.

Can I update child table without updating parent table

see table for example
CREATE TABLE parent (
id serial not null,
CONSTRAINT parent_pkey PRIMARY KEY (id)
);
CREATE TABLE child (
id serial not null,
parent_id serial not null,
username` varchar(90) NOT NULL
CONSTRAINT child_pkey PRIMARY KEY (id),
CONSTRAINT parent_fk FOREIGN KEY (parent_id)
REFERENCES parent (id)
ON DELETE RESTRICT
ON UPDATE RESTRICT
);
is there anyway i can update the username in child table? if yes how can i update it with php code.
if no what is the other option?
UPDATE `child` SET `username` = '$username' WHERE id = '$id'
replace $username and $id with your desired values.

delete in adjacency table

I have an adjacency table with parent and child elements and when I delete my parent element I would like to delete all his child.
My table:
id name parent
1 Name1 null
2 SubName1 1
When I'm trying to delete row with id=1 I would like to delete and id=2
How can I do this?
My table:
CREATE TABLE IF NOT EXISTS `cats` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`parent` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `parent` (`parent`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
Foreign keys could be the solution.
How you create them is dependent on your used Database.
At foreign keys there is a primary key defined which is like a "parent", if the parent gets deleted the childs get deleted to if you define it.

PDO: Integrity constraint violation (UPDATE TABLE)

First Table:
CREATE TABLE Portfolio_Categories
(
cat_id int(11) NOT NULL,
cat_title varchar(255) NOT NULL,
cat_dir varchar(255) NOT NULL
)
ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1;
Second Table:
CREATE TABLE Portfolio_Images
(
img_id int(11) NOT NULL,
cat_id int(11) NOT NULL,
img varchar(255) NOT NULL,
img_title varchar(255) DEFAULT NULL
)
ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=latin1 COMMENT='Table to store the Portfolio Images';
Constraints:
ALTER TABLE Portfolio_Categories
ADD PRIMARY KEY (cat_id);
ALTER TABLE Portfolio_Images
ADD PRIMARY KEY (img_id), ADD KEY cat_id (cat_id), ADD KEY img_id (img_id);
ALTER TABLE Portfolio_Images ADD CONSTRAINT cat_id FOREIGN KEY
(cat_id) REFERENCES Portfolio_Categories (cat_id);
My PHP Code:
$query = "UPDATE
Portfolio_Images
SET
Portfolio_Images.img = :new_img,
Portfolio_Images.img_title = :new_tit,
Portfolio_Images.cat_id =
(SELECT t_cat.cat_id FROM (SELECT * FROM Portfolio_Categories) AS t_cat WHERE t_cat.cat_title = :new_cat)
WHERE
Portfolio_Images.img = :old_img;";
$stmt = $_MySQLConn->prepare($query);
$stmt->bindParam(':new_img', $new_img);
$stmt->bindParam(':new_tit', $new_tit);
$stmt->bindParam(':new_cat', $new_cat);
$stmt->bindParam(':old_img', $old_img);
if($stmt->execute())
{
$return_value = array('success'=>true,
'new_img:'=>$new_img,
'new_tit'=>$new_tit,
'new_cat'=>$new_cat,
'old_img'=>$old_img);
}
else
{
$return_value = array('success'=>false,'error_code'=>'Could not execute query');
}
What should it do:
It should update my table without any error (as it does if I run the statement directly)
What does it do:
PHP shows me this error message:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or
update a child row: a foreign key constraint fails
(1_new.Portfolio_Images, CONSTRAINT cat_id FOREIGN KEY
(cat_id) REFERENCES Portfolio_Categories (cat_id))
This means that you are inserting a row in Portfolio_Images where the value in Portfolio_Images.cat_id does not exist in Portfolio_Categories.cat_id.
In other words, if in Portfolio_Categories.cat_id you only have the values 1, 2, 4 you can only insert in Portfolio_Images.cat_id the values 1, 2 or 4.

How to tell which columns have been set to CASCADE in mysql

I'm curious to know if there's away to tell which columns have been set to CASCADE using mysql. Doing DESC TABLE; doesn't appear to produce anything obvious. Any suggestions?
Since MySQL 5.1.10, you can obtain this information from the INFORMATION_SCHEMA tables by joining REFERENTIAL_CONSTRAINTS to KEY_COLUMN_USAGE:
SELECT kcu.COLUMN_NAME
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc
JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu
USING (CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA, CONSTRAINT_NAME)
WHERE 'CASCADE' IN (rc.DELETE_RULE, rc.UPDATE_RULE)
AND kcu.TABLE_SCHEMA = DATABASE()
AND kcu.TABLE_NAME = 'my_table'
You can use the:
show create table tableName;
which will output a create table that has the references to cascading deletes.
Example snagged from the docs:
mysql> SHOW CREATE TABLE ibtest11c\G
*************************** 1. row ***************************
Table: ibtest11c
Create Table: CREATE TABLE `ibtest11c` (
`A` int(11) NOT NULL auto_increment,
`D` int(11) NOT NULL default '0',
`B` varchar(200) NOT NULL default '',
`C` varchar(175) default NULL,
PRIMARY KEY (`A`,`D`,`B`),
KEY `B` (`B`,`C`),
KEY `C` (`C`),
CONSTRAINT `0_38775` FOREIGN KEY (`A`, `D`)
REFERENCES `ibtest11a` (`A`, `D`)
ON DELETE CASCADE ON UPDATE CASCADE, // <--- This is what you are looking for
CONSTRAINT `0_38776` FOREIGN KEY (`B`, `C`)
REFERENCES `ibtest11a` (`B`, `C`) // <--- This is what you are looking for
ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=INNODB CHARSET=latin1
1 row in set (0.01 sec)

Categories