Обновление PDO MYSQL, только если отличается
У меня есть веб-программа, которая позволяет администратору обновлять информацию пользователя... При этом я хочу, чтобы обновлялись только столбцы, которые действительно были "обновлены"...
Я провел немало исследований по этому вопросу, и кажется, что все методы используют устаревшие запросы, которые не используют prepare
заявление, чтобы избежать ввода...
Может кто-нибудь, пожалуйста, помогите мне с заявлением?
По сути в psuedocode:Update FIRSTNAME if $editedUserdata['firstname'] != FIRSTNAME, LASTNAME if $editedUserData['lastname']
! = LASTNAME... и т.д...
Вот что у меня есть для почтового индекса...
$password = sha1($password);
$editedUserData = array(
'firstname' => $firstname,
'lastname' => $lastname,
'username' => $username,
'password' => $password,
'cellphone' => $cellphone,
'security_level' => $seclvl,
'email' => $email,
'direct_phone' => $direct,
'ext_num' => $extension,
'is_active' => $userflag
);
Тогда это должно быть что-то вроде
$query = $this->db->prepare('UPDATE FIRSTNAME if(?) IS NOT FIRSTNAME, LASTNAME if(?) IS NOT LASTNAME, USERNAME if (?) IS NOT USERNAME.... VALUES (:firstname, :lastname, :username).....'
if ($query -> execute($editedUserData)) {
more code....
4 ответа
Возможно, я не понимаю проблему, которую вы пытаетесь решить, но вам не нужно проверять, изменилось ли значение поля.
Если значение поля равно "A" и вы поставили "A", оно останется прежним, в противном случае, если вы добавите "B", оно будет обновлено, как и ожидалось
Готовое заявление будет что-то вроде
$stmt = $dbh->prepare("
UPDATE table_name
SET
field1 = :value1,
field2 = :value2
WHERE
field0 = :key
");
$stmt->bindParam(':value1', $value1, PDO::PARAM_STR);
$stmt->bindParam(':value2', $value2, PDO::PARAM_STR);
$stmt->bindParam(':key', $key, PDO::PARAM_INT);
$stmt->execute()
Согласно документации MySQL - ссылка: ( http://dev.mysql.com/doc/refman/5.0/en/update.html)
"Если вы установите для столбца значение, которое он имеет в данный момент, MySQL заметит это и не обновит его".
Запустите один оператор, чтобы обновить строку.
Во-первых, какой уникальный идентификатор строки в users
таблица, есть ли уникальный userid
или же username
? Вам понадобится предложение WHERE в операторе UPDATE, чтобы обновлялась только эта строка.
Нормативный шаблон для оператора UPDATE для обновления нескольких столбцов в одной строке выглядит следующим образом:
UPDATE users
SET col2 = 'value'
, col3 = 'another value'
, col4 = 'fi'
WHERE idcol = idvalue ;
Чтобы использовать подготовленный оператор с PDO, текст SQL может выглядеть примерно так, если вы используете именованные заполнители:
UPDATE users
SET col2 = :col2_value
, col3 = :col3_value
, col4 = :col4_value
WHERE idcol = :id_value
Или это, если вы используете позиционную нотацию для заполнителей:
UPDATE users
SET col2 = ?
, col3 = ?
, col4 = ?
WHERE idcol = ?
(Мое личное предпочтение - использовать именованные заполнители, а не позиционные, но любой из них будет работать.)
Вот как я это сделаю, запустив подготовку, затем bind_param, а затем выполнить.
$sql = "UPDATE users
SET col2 = :col2_value
, col3 = :col3_value
, col4 = :col4_value
WHERE idcol = :id_value ";
$stmt = $dbh->prepare($sql);
$stmt->bindParam(':col2_value', $col2_val, PDO::PARAM_STR);
$stmt->bindParam(':col3_value', $col3_val, PDO::PARAM_STR);
$stmt->bindParam(':col4_value', $col4_val, PDO::PARAM_STR);
$stmt->bindParam(':id_value' , $id_val, PDO::PARAM_STR);
$stmt->execute();
Чтобы сделать что-то другое, динамически создать текст SQL и настроить вызовы bindParam, это добавит ненужную сложность к коду. Для этого нет никакого преимущества в производительности; когда выполняется этот оператор UPDATE, MySQL должен заблокировать строку и сохранить новую копию строки. На самом деле он ничего не сохраняет (кроме нескольких байтов передачи данных), чтобы избежать отправки значения столбца, которое не изменилось.
Если вы действительно хотите использовать случаи, прочитайте это.
Нет причин делать это в вашем случае, как указано в комментариях @spencer7593:
Это НАМНОГО больше накладных расходов... обходы базы данных, анализ оператора, разработка плана выполнения, выполнение оператора, получение блокировок, возвращение статуса, проверка состояния клиентом и т. Д. Это просто кажется неэффективным подходом.
Я предполагаю, что любая СУБД достаточно умна, чтобы заметить, что кэши и т. Д. Не должны пересчитываться (если ничего не меняется), если в этом проблема.