Удалить значения в списке через запятую из базы данных - PullRequest
5 голосов
/ 20 октября 2011

У меня есть таблица в моей базе данных MySQL, которая называется 'children'.В этой таблице есть строка с именем «желания» (разделенный запятыми список дочерних элементов списка желаний).Мне нужно иметь возможность обновить этот список, чтобы он удалял только одно значение.то есть список = обычные джинсы размера 12, доска для серфинга, бейсболка Red Sox;Я хочу удалить Surfboard.

Мой запрос сейчас выглядит следующим образом

$select = mysql_query('SELECT * FROM children WHERE caseNumber="'.$caseNum.'" LIMIT 1 ');
    $row = mysql_fetch_array($select);

    foreach ($wish as $w) {
        $allWishes = $row['wishes'];
        $newWishes = str_replace($w, '', $allWishes);
        $update = mysql_query("UPDATE children SET wishes='$newWishes' WHERE caseNum='".$caseNum."'");
}

Но запрос UPDATE ничего не удаляет.Как я могу делать то, что мне нужно?

Ответы [ 6 ]

3 голосов
/ 20 октября 2011

Используя эти пользовательские REGEXP_REPLACE() функции , вы можете заменить его пустой строкой:

UPDATE children SET wishes = REGEXP_REPLACE(wishes, '(,(\s)?)?Surfboard', '') WHERE caseNum='whatever';

К сожалению, вы не можете просто использовать простой старый REPLACE() потому что вы не знаете, где в строке появляется надпись «Surfboard».Фактически, приведенное выше регулярное выражение, вероятно, потребует дополнительной настройки, если в начале или в конце появляется 'Surfboard'.

Возможно, вы могли бы обрезать оставшиеся передние и конечные запятые следующим образом:

UPDATE children SET wishes = TRIM(BOTH ',' FROM REGEXP_REPLACE(wishes, '(,(\s)?)?Surfboard', '')) WHERE caseNum='whatever';

Так что здесь происходит?Регулярное выражение удаляет 'Surfboard' плюс необязательную запятую и пробел перед ним.Затем окружающая функция TRIM() исключает возможную начальную запятую в случае, если в начале строки возникла надпись «Surfboard».С этим, вероятно, может справиться и регулярное выражение, но, честно говоря, я слишком устал, чтобы ломать голову над этим.

Примечание: Я никогда не использовал их сам и не могу поручиться за ихэффективность или надежность, но это место для начала.И, как другие упоминают в комментариях, вы действительно должны иметь их в нормализованной таблице пожеланий, а не в виде строки, разделенной запятыми.

Обновление

Мышлениеоб этом больше, я более неравнодушен к простому использованию встроенного REPLACE(), а затем к очистке лишней запятой, где вы можете получить две запятые подряд.Это ищет две запятые рядом, как будто не было пробелов, разделяющих ваши оригинальные элементы списка.Если элементы были разделены запятыми и пробелами, измените ',,' на ', ,' во внешнем вызове REPLACE().

UPDATE children SET wishes = TRIM(BOTH ',' FROM REPLACE(REPLACE(wishes, 'Surfboard', ''), ',,', ',')) WHERE caseNum='whatever';
1 голос
/ 20 октября 2011

Не совсем прямой ответ на ваш вопрос, но, как говорит Дарен, лучше иметь пожелания в качестве собственной таблицы.Возможно, вы могли бы изменить схему базы данных, чтобы у вас было 3 таблицы, например:

children
-> caseNum
-> childName

wishes
-> caseNum
-> wishId
-> wishName

childrensWishes
-> caseNum
-> wishId

Затем, чтобы добавить или удалить желание для ребенка, вы просто добавляете или удаляете соответствующую строку из childrensWishes.Ваш текущий дизайн затрудняет манипулирование (как вы находите), а также подвергает вас риску противоречивых данных.

В качестве более прямого ответа вы можете исправить свой текущий путь, получив список пожеланий,взорвать () их, удалив из массива ненужный, и вывести () обратно в строку для обновления базы данных.

0 голосов
/ 26 августа 2016

Вы можете создать такую ​​функцию:

CREATE  FUNCTION `remove_from_set`(v int,lst longtext) RETURNS longtext CHARSET utf8
BEGIN
set @lst=REPLACE(@lst, ',,', ',');
set @lng=LENGTH(@lst) - LENGTH(REPLACE(@lst, ',', ''))+1;
set @p=find_in_set(@v,@lst);
set @l=SUBSTRING_INDEX( @lst, ',', @p-1);
set @r=SUBSTRING_INDEX( @lst, ',', @p-@lng);
IF @l!='' AND @r!='' THEN
    return CONCAT(@l,',',@r);
ELSE
    RETURN CONCAT(@l,'',@r);
END IF;
END

Использование:

SELECT remove_from_set('1,,2,3,4,5,6',1)
0 голосов
/ 16 апреля 2016

Я думаю, что лучший ответ на этот вопрос здесь Лучший способ удалить значение из поля SET?

запрос должен быть таким, который охватывает, значение или значение, или толькозначение в столбце, разделенном запятыми

UPDATE yourtable
SET
  categories =
    TRIM(BOTH ',' FROM
      REPLACE(
        REPLACE(CONCAT(',',REPLACE(col, ',', ',,'), ','),',2,', ''), ',,', ',')
    )
WHERE
  FIND_IN_SET('2', categories)

Здесь вы можете указать условие в предложении where.для более подробной информации см. ссылку выше.

0 голосов
/ 20 октября 2011

Иметь пожелания, индексированные в массиве, который затем сериализуется, может быть идеей, в противном случае вам потребуется извлечь строку, нарезать ее, удалить ненужную часть, а затем объединить остатки.Это можно сделать с помощью функции explode () .

Если бы вы использовали массив, вы бы получили массив и затем отсортировали его с помощьюЦикл, подобный следующему:

// Wishes array:
// Array (
//      [0] Regular Jeans
//      [1] Surfboard
//      [2] Red Sox Baseball Cap
// )

$wishes = $row['wishes']; // This is a serialized array taken from the database
$wishes = unserialize($wishes);

foreach ($wishes as $key => $value) {
    if ($value == 'Surfboard') {
        unset($wishes[$key]);
        break;
    }
}

$wishes = serialize($wishes);
// Update database

Имейте в виду, что index [1] теперь не будет существовать в массиве, поэтому, если вы хотите иметь чистый массив, вы должны перебрать массив и заставить его создатьновый массив сам по себе:

foreach ($wishes as $wishes) {
    $newArray[] = $wishes;
}
0 голосов
/ 20 октября 2011

Таблица пожеланий имеет следующий формат:

caseNumber,wish

Тогда вы получаете все пожелания ребенка, например:

SELECT * FROM children c left join wishes w on c.caseNumber = w.caseNumber WHERE c.caseNumber= ?

Удаление желания становится:

DELETE from wishes where caseNumber = ?

Добавление желания становится:

INSERT into wishes (caseNumber,wish) values (?,?)

Возвращение одного желания становится:

SELECT * FROM children c left join wishes w on c.caseNumber = w.caseNumber WHERE c.caseNumber= ? LIMIT 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...