Первоначальный вопрос (позже расширенный - см. Ниже):
Возможно ли обновить поле со значением из другого поля и в этом процессе заменить строку внутри этого обновленного значения?
Я попробовал следующее (очень упрощенное):
UPDATE table1 SET field1 = REPLACE(field2, string1, string2);
Пример: field2
содержит "темно-синий", string1
- "синий", string2
- "красный".
Я ожидал, что все значения из field2
будут скопированы в field1
, но при копировании заменит любой экземпляр string1
который будет заменен на string2
в field1
. Поэтому в моем примере значение field2
должно стать "темно-красным".
Но это только скопировало неизменные значения field2
в field1
без каких-либо изменений/изменений. (в моем примере field2
становится "темно-синим")
EDIT/ADDITION:
Скрипты, которые @axiac и @2SRTVF создали и связали в своих комментариях, показали мне, что код, который я написал, фактически работает. Большое спасибо вам обоим!
Однако мой исходный код встроен в подготовленный оператор. Также подготовленное выражение работает, как и ожидалось. Но этот подготовленный оператор находится внутри цикла foreach
который проходит через массив, и в этой ситуации запрос обновления не работает...
Вот код, который я действительно использую:
$db = new mysqli("my_host", "my_user", "my_pw", "my_database");
foreach($my_array AS $x=>$y) {
if($ps = $db->prepare("UPDATE table1 SET field1 = REPLACE(field2, ?, ?) ")) {
$ps->bind_param("ss", $x, $y);
$ps->execute();
$ps->close();
}
}
Массив содержит пары ключ/значение, один из них в моем примере выше будет blue/red
.
Ваша проблема - ваш цикл. Все замены, которые происходят в первом count($my_array)-1
проходят через цикл, отбрасываются последним проходом, потому что UPDATE
всегда копирует из текущего значения field2
, а не (возможно, ранее измененную копию field1
. Попробуйте добавить это перед циклом:
UPDATE table1 SET field1 = field2
а затем измените запрос в цикле на:
UPDATE table1 SET field1 = REPLACE(field1, ?, ?)
Обратите внимание, что при подготовке запроса в цикле вы теряете преимущество в эффективности подготовленных запросов. Было бы лучше написать его как:
if ($ps = $db->prepare("UPDATE table1 SET field1 = REPLACE(field1, ?, ?) ")) {
foreach ($my_array as $x => $y) {
$ps->bind_param("ss", $x, $y);
$ps->execute();
}
$ps->close();
}
Итак, если, например, ваша таблица содержит
field1 field2
x dark blue
y light green
и $my_array = array('blue' => 'red', 'green' => 'pink')
затем после запуска этого кода вы получите:
field1 field2
dark red dark blue
light pink light green
Назначения UPDATE с одним столом обычно оцениваются слева направо. Что вы можете сделать, так это:
UPDATE table1 SET field1 = field2, field2 = REPLACE(field2, string1, string2);
field1
. field2
не должно быть изменено.
string1
присутствует вfield2
иfield2
внимание на заглавные буквы.REPLACE()
чувствителен к регистру.