Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Не работает каскадное удаление
 
 автор: kate_2   (05.06.2006 в 21:26)   письмо автору
 
 

Подскажите почему не работает каскадное удаление?
Выдаёт ошибку:

SQL-запрос:
DELETE FROM 'razdel' WHERE 'idr' = '17' LIMIT 1

Ответ MySQL:
#1217 - Cannot delete or update a parent row: a foreign key constraint fails

CREATE TABLE 'razdel' (
'idr' smallint(5) unsigned NOT NULL auto_increment,
'pos' int(11) NOT NULL default '0',
'name' tinytext NOT NULL,
'addr' tinytext NOT NULL,
'title' tinytext NOT NULL,
'keyw' tinytext NOT NULL,
'desc_r' tinytext NOT NULL,
'h1' tinytext NOT NULL,
'content' text NOT NULL,
'hide' enum('show','hide') NOT NULL default 'show',
PRIMARY KEY ('idr'),
KEY 'hide' ('hide')
) TYPE=InnoDB ;


CREATE TABLE 'pages' (
'idp' int(6) unsigned NOT NULL auto_increment,
'idr' smallint(5) unsigned NOT NULL default '0',
'pos' int(11) NOT NULL default '0',
'name' tinytext NOT NULL,
'addr' tinytext NOT NULL,
'title' tinytext NOT NULL,
'keyw' tinytext NOT NULL,
'desc_p' tinytext NOT NULL,
'h1' tinytext NOT NULL,
'content' text NOT NULL,
'hide' enum('show','hide') NOT NULL default 'show',
PRIMARY KEY ('idp'),
KEY 'idr' ('idr'),
KEY 'hide' ('hide')
) TYPE=InnoDB ;

Каскадное обновление по полю hide работает, а каскадное удаление по полю idr не хочет....

   
 
 автор: cheops   (05.06.2006 в 22:01)   письмо автору
 
   для: kate_2   (05.06.2006 в 21:26)
 

А внешний ключ как был объявлен?

   
 
 автор: kate_2   (05.06.2006 в 22:06)   письмо автору
 
   для: cheops   (05.06.2006 в 22:01)
 

вот так

ALTER TABLE 'pages'
ADD CONSTRAINT 'pages_ibfk_10' FOREIGN KEY ('hide') REFERENCES 'razdel' ('hide') ON UPDATE CASCADE,
ADD CONSTRAINT 'pages_ibfk_9' FOREIGN KEY ('idr') REFERENCES 'razdel' ('idr') ON DELETE CASCADE;

   
 
 автор: cheops   (06.06.2006 в 10:43)   письмо автору
 
   для: kate_2   (05.06.2006 в 22:06)
 

Попробуйте удалить пока ключ pages_ibfk_10 - ситуация не меняется?

   
 
 автор: kate_2   (06.06.2006 в 15:02)   письмо автору
 
   для: cheops   (06.06.2006 в 10:43)
 

так без ключа работать то не будет каскадное удаление

   
 
 автор: kate_2   (06.06.2006 в 15:38)   письмо автору
 
   для: cheops   (06.06.2006 в 10:43)
 

Никак не получается...ругается на внешний ключ. при попытке удалить раздел
а при попытке обновить по полю hide страницу тоже ругается.

Вот дамп, посмотрите плиз...

---------------------------------------------------------------------------------------------------------------------

-- phpMyAdmin SQL Dump
-- version 2.6.0-pl2
-- http://www.phpmyadmin.net
--
-- Хост: localhost
-- Время создания: Июн 06 2006 г., 15:28
-- Версия сервера: 4.0.22
-- Версия PHP: 5.0.2
--
-- БД: 'cms'
--

-- --------------------------------------------------------


--
-- Структура таблицы 'pages'
--

CREATE TABLE 'pages' (
'idp' int(6) unsigned NOT NULL auto_increment,
'idr' smallint(5) unsigned NOT NULL default '0',
'pos' int(11) NOT NULL default '0',
'name' tinytext NOT NULL,
'addr' tinytext NOT NULL,
'title' tinytext NOT NULL,
'keyw' tinytext NOT NULL,
'desc_p' tinytext NOT NULL,
'h1' tinytext NOT NULL,
'content' text NOT NULL,
'hide' enum('hide','show') NOT NULL default 'hide',
PRIMARY KEY ('idp'),
KEY 'idr' ('idr'),
KEY 'hide' ('hide')
) TYPE=InnoDB AUTO_INCREMENT=7 ;

--
-- Дамп данных таблицы 'pages'
--

INSERT INTO 'pages' VALUES (2, 1, 1, 'Миссия', '/about/mission.php', 'Миссия', 'Миссия', 'Миссия', 'Миссия', 'Миссия', 'show');
INSERT INTO 'pages' VALUES (3, 1, 3, 'Контакты', '/about/contacts.php', 'Контакты', 'Контакты', 'Контакты', 'Контакты', 'Контакты',

'show');
INSERT INTO 'pages' VALUES (4, 1, 5, 'Вакансии', '/about/vacancy.php', 'Вакансии', 'Вакансии', 'Вакансии', 'Вакансии', 'Вакансии',

'show');
INSERT INTO 'pages' VALUES (5, 1, 4, 'Планы', '/about/plans.php', 'Планы', 'Планы', 'Планы', 'Планы', 'Планы', 'show');
INSERT INTO 'pages' VALUES (6, 1, 2, 'Партнёры', '/about/partners.php', 'Партнёры', 'Партнёры', 'Партнёры', 'Партнёры', 'Партнёры',

'show');

-- --------------------------------------------------------

--
-- Структура таблицы 'razdel'
--

CREATE TABLE 'razdel' (
'idr' smallint(5) unsigned NOT NULL auto_increment,
'pos' int(11) NOT NULL default '0',
'name' tinytext NOT NULL,
'addr' tinytext NOT NULL,
'title' tinytext NOT NULL,
'keyw' tinytext NOT NULL,
'desc_r' tinytext NOT NULL,
'h1' tinytext NOT NULL,
'content' text NOT NULL,
'hide' enum('hide','show') NOT NULL default 'hide',
PRIMARY KEY ('idr'),
KEY 'hide' ('hide')
) TYPE=InnoDB AUTO_INCREMENT=7 ;

--
-- Дамп данных таблицы 'razdel'
--

INSERT INTO 'razdel' VALUES (1, 1, 'О КОМПАНИИ', '/about/', 'О компании', 'О компании', 'О компании', 'О компании', 'О компании',

'show');
INSERT INTO 'razdel' VALUES (2, 2, 'УСЛУГИ', '/services/', 'УСЛУГИ', 'УСЛУГИ', 'УСЛУГИ', 'УСЛУГИ', 'УСЛУГИ', 'show');
INSERT INTO 'razdel' VALUES (3, 3, 'ПРОДУКЦИЯ', '//', 'ПРОДУКЦИЯ', 'ПРОДУКЦИЯ', 'ПРОДУКЦИЯ', 'ПРОДУКЦИЯ',

'П<STRONG>РОДУКЦИЯ</STRONG>', 'show');
INSERT INTO 'razdel' VALUES (4, 4, 'СПРАВОЧНАЯ ИНФОРМАЦИЯ', '/info/', 'СПРАВОЧНАЯ ИНФОРМАЦИЯ', 'СПРАВОЧНАЯ

ИНФОРМАЦИЯ', 'СПРАВОЧНАЯ ИНФОРМАЦИЯ', 'СПРАВОЧНАЯ ИНФОРМАЦИЯ', 'СПРАВОЧНАЯ ИНФОРМАЦИЯ', 'show');
INSERT INTO 'razdel' VALUES (5, 5, 'ПРОДУКЦИЯ', '/products/', 'ПРОДУКЦИЯ', 'ПРОДУКЦИЯ', 'ПРОДУКЦИЯ', 'ПРОДУКЦИЯ',

'ПРОДУКЦИЯ', 'show');
INSERT INTO 'razdel' VALUES (6, 6, 'ПРОЕКТЫ', '/projects/', 'ПРОЕКТЫ', 'ПРОЕКТЫ', 'ПРОЕКТЫ', 'ПРОЕКТЫ', 'ПРОЕКТЫ', 'show');

--
-- Constraints for table 'pages'
--
ALTER TABLE 'pages'
ADD CONSTRAINT 'pages_ibfk_1' FOREIGN KEY ('idr') REFERENCES 'razdel' ('idr') ON DELETE CASCADE ON UPDATE NO

ACTION,
ADD CONSTRAINT 'pages_ibfk_2' FOREIGN KEY ('hide') REFERENCES 'razdel' ('hide') ON DELETE NO ACTION ON UPDATE

CASCADE;


---------------------------------------------------------------------------------------------------------------------

Ну никак не получается...помогите!!!
Что не так? версия мускула у меня - MySQL 4.0.22-nt-log

   
 
 автор: Trianon   (06.06.2006 в 17:08)   письмо автору
 
   для: kate_2   (06.06.2006 в 15:38)
 

Я вот чего не понимаю... поле hide в обеих табицах - это ведь не ключ. Как же на него можно ссылаться?

   
 
 автор: kate_2   (06.06.2006 в 17:31)   письмо автору
 
   для: Trianon   (06.06.2006 в 17:08)
 

поле hide имеет индекс и в родительской и в дочерней таблице.
По индексам по-моему можно строить связи.
Связь нужна для каскадного обновления поля hide

   
 
 автор: Trianon   (06.06.2006 в 18:11)   письмо автору
 
   для: kate_2   (06.06.2006 в 17:31)
 

Но тогда стоит в одной любой строке таблицы razdel полю hide присвоить допустим show,
и поле во всей таблице pages тоже изменится на show.
Вообще все строки.
Так и надо?

   
 
 автор: kate_2   (06.06.2006 в 19:05)   письмо автору
 
   для: Trianon   (06.06.2006 в 18:11)
 

да так и надо чтобы при изменении в родительской таблице менялись значения соответственно в дочерней.
Но этого не происходит! Мускул выдаёт ошибку...

#1217 - Cannot delete or update a parent row: a foreign key constraint fails

   
 
 автор: Trianon   (06.06.2006 в 19:11)   письмо автору
 
   для: kate_2   (06.06.2006 в 19:05)
 

Заметьте, hide меняться будет у всех pages, а не только у тех, которые принадлежат затрагиваемому разделу.

   
 
 автор: kate_2   (06.06.2006 в 19:15)   письмо автору
 
   для: Trianon   (06.06.2006 в 19:11)
 

упс, точно, как же быть?
программно как-то писать?

а с удалением чего ему не нравится?

   
 
 автор: Trianon   (06.06.2006 в 19:20)   письмо автору
 
   для: kate_2   (06.06.2006 в 19:15)
 

А чтобы решать вопрос с удалением, левые констрайнты надо убрать. А то mySql'у от них башню сносит.

   
 
 автор: Trianon   (06.06.2006 в 19:21)   письмо автору
 
   для: kate_2   (06.06.2006 в 19:15)
 

>упс, точно, как же быть?
не пытаться тянуть связи на что-либо отличное от первичных ключей.
Кстати, поскольку модифицировать первичные ключи - дурной тон, то попадать в такие ситуации просто не получится.

>программно как-то писать?
а что - программно?
Так на так update - один запрос.

   
 
 автор: kate_2   (06.06.2006 в 19:38)   письмо автору
 
   для: Trianon   (06.06.2006 в 19:21)
 

убрать левые это вот эти 'pages_ibfk_2' ?
и заменить на что-то человеческое или вообще название убрать?
вобщем левые констрейнты убрала, всё равно удаление не пашет:(

А вот обновление работает как надо...как объяснить этот факт?

   
 
 автор: Trianon   (06.06.2006 в 19:42)   письмо автору
 
   для: kate_2   (06.06.2006 в 19:38)
 

Под левыми я имел в виду те, которые ссылаются не на первичные ключи.
У Вас это - ADD CONSTRAINT 'pages_ibfk_2' FOREIGN KEY ('hide') REFERENCES 'razdel' ('hide') ON DELETE NO ACTION ON UPDATE CASCADE;

А второе - вроде вполне нормальное.

   
 
 автор: kate_2   (06.06.2006 в 19:58)   письмо автору
 
   для: Trianon   (06.06.2006 в 19:42)
 

Так вот они как раз работают, Т.Е. происходит каскадное обновление я проверила.

А что с каскадным удалением?

Пробовала не использовать вообще каскадное обновление для поля hide, чтобы посмотреть будет ли работать удаление по idr, но удаление ни в какую не хочет работать, выдаёт ошибку....

   
 
 автор: Trianon   (06.06.2006 в 20:11)   письмо автору
 
   для: kate_2   (06.06.2006 в 19:58)
 

Я только что разрешил у себя innoDB, создал базу, импорировал Ваш дамп (исправив кавычки в именах таблиц и полей и убрав констрайнт на поле hide) и попробовал удаление.
Сношу раздел "О КОМПАНИИ" - сносятся все страницы.
Так что не знаю, как у Вас, но у меня удаление работает.

   
 
 автор: kate_2   (06.06.2006 в 20:19)   письмо автору
 
   для: Trianon   (06.06.2006 в 20:11)
 

как разрешили InnoDB?

а у Вас с констрэйнтом hide работает?

   
 
 автор: Trianon   (06.06.2006 в 20:35)   письмо автору
 
   для: kate_2   (06.06.2006 в 20:19)
 

>как разрешили InnoDB?

ну, я на денвере пробую, а в нём innoDB по умолчанию выключен в конфиге mysql строкой skip-innodb
чтобы зазря процессор не жечь, все ж таки innoDB ресурсы ест сильнее чем MyISAM.

>
>а у Вас с констрэйнтом hide работает?
откровенно говоря не пробовал. Сейчас попробую.
....
Попробовал. Тоже работает. В смысле - удаление раздела О Компании приводит к удаелнию страниц.

   
 
 автор: kate_2   (06.06.2006 в 20:42)   письмо автору
 
   для: Trianon   (06.06.2006 в 20:35)
 

да у меня обновление с hide работает, может он умный и сам понимает что ограничитеть (обновления дочерних таблиц) - это первичный ключ в родительской....

а удаление каким чудом у Вас работает? у меня не хочет никак, всё та же ошибка

   
 
 автор: Trianon   (06.06.2006 в 20:47)   письмо автору
 
   для: kate_2   (06.06.2006 в 20:42)
 

>а удаление каким чудом у Вас работает? у меня не хочет
>никак, всё та же ошибка
не знаю... впрочем, у меня MySQL посвежее: 5.0.18-max . Может, поэтому.

   
 
 автор: Trianon   (06.06.2006 в 20:51)   письмо автору
 
   для: kate_2   (06.06.2006 в 20:42)
 

>да у меня обновление с hide работает, может он умный и сам
>понимает что ограничитеть (обновления дочерних таблиц) - это
>первичный ключ в родительской....
Я не понимаю смысла вытягивать это поле в родительскую таблицу.
Только чтобы чуть-чуть упростить запрос изменения поля для раздела?
Тем более что поведение явно напоминает некий побочный эффект, нежели документированное действие.
Если Вы пришлете данные страниц для других разделов, я могу проверить и каскадное обновление.
Только всё равно это игра на грани фола. По-моему.

   
 
 автор: kate_2   (06.06.2006 в 20:59)   письмо автору
 
   для: Trianon   (06.06.2006 в 20:51)
 

>Я не понимаю смысла вытягивать это поле в родительскую таблицу.
>Только чтобы чуть-чуть упростить запрос изменения поля для раздела?
Я не меняю поля раздела.
У меня 2 таблицы razdel и pages.
razdel - родительская
pages - дочерняя
В razdel и pages есть в каждой по полю hide.
Необходимо чтобы при изменении поля hide в родительской таблице razdel менялись всеполя в дочерней таблице pages.
Я слеласа по индексу для полей hide в кажной таблице.

и написала такое выражение
ADD CONSTRAINT 'pages_ibfk_2' FOREIGN KEY ('hide') REFERENCES 'razdel' ('hide') ON DELETE NO ACTION ON UPDATE CASCADE;

А про каскадное удаление писали, что должно работать в версии 3.22.22 (точно не помню, но у сеня то 4 с чем-то)

   
 
 автор: Trianon   (06.06.2006 в 21:10)   письмо автору
 
   для: kate_2   (06.06.2006 в 20:59)
 

>Я не меняю поля раздела.
>Необходимо чтобы при изменении поля hide в родительской таблице razdel
:)

   
 
 автор: kate_2   (06.06.2006 в 21:12)   письмо автору
 
   для: Trianon   (06.06.2006 в 21:10)
 

ну Вы поняли? :)
что посоветуете ?
меня больше всего удаление волнует...хотя обновление тоже, но оно хотя бы работает...

   
 
 автор: Trianon   (06.06.2006 в 21:17)   письмо автору
 
   для: kate_2   (06.06.2006 в 21:12)
 

Что посоветую? Сделать как я.
С нуля создать еще одну БД, и в ней эту пару таблиц.
Сперва с одним ограничением для каскадного удаления.
И проверить.
Во всяком случае любые побочные эффекты уйдут.

   
 
 автор: Trianon   (06.06.2006 в 21:24)   письмо автору
 
   для: kate_2   (06.06.2006 в 21:12)
 

Между прочим. Диагностика заставляет подумать: а руками удалить все страницы, связанные с удаляемым разделом в принципе можно? Может из-за каких-то других ограничений системе не удается удалить pages?

   
 
 автор: kate_2   (06.06.2006 в 21:36)   письмо автору
 
   для: Trianon   (06.06.2006 в 21:24)
 

может быть...я уже запарилась

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования