|
|
|
| необходимо каскадно обновить/удалить только зависимые от id записи. количество уровней заранее неизвестно.
нпр, id
5550000000
5551000000
5551000001
5551000002
5551100000 5551100001
в базе:
id | kod (определяет вышестоящий уровень)
5551000000 | 5550000000
5551100001 | 5551100000
присваиваем 5551000000=666100000=> должны измениться только 6661000001
6661000002
$query = "UPDATE catalogue SET id = CONCAT('$new_prefix', SUBSTRING(id, 1+LENGTH('$old_prefix')))
WHERE id like '{$old_prefix}_______' and
kod = $id or kod2 = $id or
(kod or kod2 in
(select id from catalogue where id=$id
or kod or kod2 in
(select id from catalogue where id=$id
or (kod or kod2) in
(select id from catalogue where id=$id
or (kod or kod2) in
(select id from catalogue where id=$id
|
"UPDATE catalogue SET kod = CONCAT('$new_prefix', SUBSTRING(kod, 1+LENGTH('$old_prefix')))
WHERE kod like '{$old_prefix}_______'and
kod = $id or kod2 = $id[-//-//query]";
|
"UPDATE catalogue SET kod2 = CONCAT('$new_prefix', SUBSTRING(kod2, 1+LENGTH('$old_prefix')))
WHERE kod2 like '{$old_prefix}_______'and
kod = $id or kod2 = $id[-//-//query]";
|
$query4="delete * from catalogue where id=$id
or kod= $id or kod2 = $id or
(kod or kod2 in
(select id from catalogue where id=$id or
kod or kod2 in
(select * from catalogue where id=$id or
kod or kod2
(select * from catalogue where id=$id or
or kod or kod2select * from catalogue where id=$id
)
))
))";
|
не знаю как исправить. | |
|
|
|
|
|
|
|
для: Medulla
(18.06.2007 в 11:02)
| | покажите, пожалуйста, структуру и несколько строк данных из дампа. которые иллюстрировали бы процесс.
Очень трудно разобраться, как у Вас связаны записи... | |
|
|
|
|
|
|
|
для: Trianon
(18.06.2007 в 11:06)
| | id (bigint) kod (bigint) kod2 (bigint)+pkey autoinc
4692000000////4690000002/////// 4690000000
4692000001////4690000002//////// 4692000000
4692010000////4692010001/////// 4692000000
4692010001//// 4690000002////// 4692010000
4692010002////4692010001//////// 4692010000
4692020000//// 4692020001///// 4692000000
4692020001//// 4690000002//// 4692020000
4692020002//// 4692020001//// 4692020000
4692020003//// 4692020001//// 4692020000
4693020003//// 4693020002//// 4693020000
4693020004//// 4693020002//// 4693020000
4693020005//// 4693020002//// 4693020000
4693020006//// 4693020002//// 4693020000
меняем 4692000000 на 7770000000
должны изменится все, кроме 4 последних строк
46920 в качестве параметра выборки использовать нельзя, т.к. возможны другие коды, кот. связаны с 4692000000 по kod, kod1 | |
|
|
|
|
|
|
|
для: Medulla
(18.06.2007 в 11:30)
| | >меняем 4692000000 на 7770000000
4692000000 и 7770000000 - это префиксы замены?
в каких полях?
Во всех трех?
какое поле какому соответствует - Вы не написали. | |
|
|
|
|
|
|
|
для: Trianon
(18.06.2007 в 12:33)
| | >4692000000 и 7770000000 - это префиксы замены?
$id - 4692000000.
$id2 -7770000000
префикс 469 заменить на 777
>в каких полях?
>Во всех трех?
в 3. id, kod (2 столбец), kod2 (3 столбец)
2 и 3 столбец прямо/ косвенно (через несколько уровней) связаны с $id.
>какое поле какому соответствует - Вы не написали.
? | |
|
|
|
|
|
|
|
для: Medulla
(18.06.2007 в 12:45)
| | Похоже, я понял.
Примерная схема алгоритма такова.
Потребуется ввести доп. поле (state)
количество циклов (и запросов) нужно как минимум равное глубине связи.
Каждый цикл будет вычислять записи очередного уровня глубины, помечая их в state флажками.
Когда не останется модифицированных записей - нужно пройти еще раз по всей таблице, и выполнить замену помеченных полей. | |
|
|
|
|
|
|
|
для: Trianon
(18.06.2007 в 13:58)
| | >>Каждый цикл будет вычислять записи очередного уровня глубины, помечая их в state флажками.
получается вычислять записи только 1 уровня, как в delete, так и update.
не могу посторить запрос на вычисление уровня ниже. | |
|
|
|
|
|
|
|
для: Medulla
(18.06.2007 в 14:09)
| | что-то такое...
UPDATE tab AS t1 JOIN tab AS t2 ON t1.id = t2.kod OR t1.id=t2.kod2
SET t1.state = 1 WHERE
t2.state IS NOT NULL
AND
(t2.kod LIKE '{$prefix}______'
OR
t2.kod2 LIKE '{$prefix}______' )
|
| |
|
|
|
|
|
|
|
для: Trianon
(18.06.2007 в 13:58)
| |
$query="select id from catalogue where id ='$id' or kod='$id' or kod2 ='$id'";
$query2="select id from catalogue where id = $query";
| так? | |
|
|
|
|
|
|
|
для: Medulla
(18.06.2007 в 14:27)
| | селект-то зачем?
Вам же менять надо, а не глядеть...
Если хотите глядеть - глядите все
SELECT id FROM catalogue WHERE state IS NOT NULL | |
|
|
|
|
|
|
|
для: Trianon
(18.06.2007 в 14:37)
| | плохой пример) имела ввиду присвоение переменной.
допустим:
$level= "delete * from catalogue where pid in (select id from catalogue where pid='$id' or pid2='$id') or pid2 in (select id from catalogue where pid='$id' or pid2='$id')";
| так работает.
присвоение+передача в запрос
$ main ="select id from catalogue where pid='$id' or pid2='$id'";
$result = mysql_query($main);
| возвращает некорректную информацию.
возможно ли его использовать? | |
|
|
|
|
|
|
|
для: Medulla
(18.06.2007 в 17:51)
| | Вы хотите получить массив с id-ами в php?
Это делается несколько по-другому.
$sql ="select id from catalogue where pid='$id' or pid2='$id'";
$res = mysql_query($sql);
for($result = array(); $row = mysql_fetch_assoc($res) ;)
$result[] = $row['id'];
|
На больших объемах таблицы памяти может и не хватить. | |
|
|
|
|
|
|
|
для: Trianon
(18.06.2007 в 17:58)
| | Между прочим...
по теме. При движке InnoDB возможен перенос некоторых каскадных действий на сам сервер. Там есть ограничения чужого ключа ON UPDATE CASCADE .... и ON DELETE CASCADE ....
Не то что это Вам сильно надо, раз не пользуетесь,.... но упомянуть стоит. | |
|
|
|
|
|
|
|
для: Trianon
(18.06.2007 в 18:09)
| | где можно прочитать подробнее? | |
|
|
|
|
|
|
|
для: Trianon
(18.06.2007 в 17:58)
| |
$sql ="select id from catalogue where pid='$id' or pid2='$id'";
$res = mysql_query($sql);
for($result = array(); $row = mysql_fetch_assoc($res) ;)
$result[] = $row['id'];
$level2= "select id from catalogue where pid='$result' or pstaff ='$result'";
$result2 = mysql_query($level2);
$num_rows = mysql_num_rows($result2);
<p>На удаление помечено '."$num_rows \n".' записей. </p>';
for ($i=0; $i <$num_rows; $i++)
{
$row = mysql_fetch_assoc($result2);
echo '<p><strong>'.($i+1).'. Код: ';
echo specialchars(stripslashes($row['id']));
echo '</strong><br />Название: ';
echo stripslashes($row['dolg']);
echo '</p>';
}
mysql_free_result($result1) or die ("Ошибка1.");
mysql_close($connection);
|
отобразились некоррекктные данные, как и в первом случае.
почему после for не нужны { }? | |
|
|
|
|
|
|
|
для: Medulla
(18.06.2007 в 19:12)
| | Вы явно хотите другого....
<?
$sql ="select id from catalogue where pid='$id' or pid2='$id'";
$res = mysql_query($sql);
for($result = array(); $row = mysql_fetch_assoc($res) ;)
$result[] = $row['id'];
// массив id-ов. array('23416','283741','9123874')
$result = empty($result) ? "()" : ("('". implode("','", $result) ."')");
//список id-ов. строка "('23416','283741','9123874')"
$level2= "select id from catalogue where pid IN $result or pstaff IN $result";
$result2 = mysql_query($level2);
|
Второй запрос может быть отклонен из-за размера....
>почему после for не нужны { }?
после for нужен оператор тела.
Ему необязательно быть большим составным оператором. В данном случае подошел простой - оператор вычисления выражения. | |
|
|
|
|
|
|
|
для: Trianon
(18.06.2007 в 19:21)
| | усложняю себе задачу) спасибо. | |
|
|
|
|
|
|
|
для: Trianon
(18.06.2007 в 19:21)
| | delete удаляет $id + все зависимые коды
$level2= "delete * from catalogue where * id='$id' or pid in
(select id from catalogue where pid in (select id from catalogue where pid in
(select id from catalogue where pid='$id' or pid2='$id') or pid2 in
(select id from catalogue where pid='$id' or pid2='$id')) or pid2 in
(select id from catalogue where pid in
(select id from catalogue where pid='$id' or pid2='$id') or pid2 in
(select id from catalogue where pid='$id' or pid2='$id'))) or pid2 in
(select id from catalogue where pid in (select id from catalogue where pid in
(select id from catalogue where pid='$id' or pid2='$id') or pid2 in
(select id from catalogue where pid='$id' or pid2='$id')) or pid2 in
(select id from catalogue where pid in (select id from catalogue where pid='$id' or pid2='$id') or pid2 in
(select id from catalogue where pid='$id' or pid2='$id')))";
|
update возвращает ошибку.
$level2 = "update catalogue set status = '1' where *
$result2 = mysql_query($level2);
mysql_free_result($result2) or die ("Ошибка1.");
|
| |
|
|
|
|
|
|
|
для: Medulla
(19.06.2007 в 13:58)
| | это какие-то совсем ужасные запросы...
Там не нужно звездочки ни в том, ни в другом.
Когда исполняете запрос - контролируйте сразу, удачно ли он выполнился.
$level2 = "delete from catalogue where status
$result2 = mysql_query($level2) or die("Error in $level2: ". mysql_error());
mysql_free_result($result2);
|
А что, идею с пошаговой пометкой реализовать не получилось? | |
|
|
|
|
|
|
|
для: Trianon
(19.06.2007 в 15:16)
| | пока получилось так: 1 раз выполняю _ужасный_ запрос с вложенными подзапросами [>8 уровней]
передаю в $result все id возвращенные запросом.
$query = "update catalogue set status = '1' where id in $result";
|
потом update, delete в зависимости от условий/действий пользователя, где
ошибка была здесь:
from catalogue where id='$id' or pid='$id' or pid2='$id'
|
а уж потом
or pid in (select id from catalogue where pid in (select
|
ps * не самое лучшее усл. обозначения подзапросов из пред. кода)
большое спасибо за помощь. | |
|
|
|
|
|
|
|
для: Medulla
(18.06.2007 в 11:02)
| | >'{$old_prefix}_______'and
Между закрывающе кавычкой и and действительно пробела нет или это опечатка? | |
|
|
|
|
|
|
|
для: cheops
(18.06.2007 в 11:10)
| | опечатка | |
|
|
|