Обновите строку SQL, если существует, создайте, если не существует (в PHP)

0

Я пытаюсь обновить значение для пользователя, не зная, существует ли пользователь или нет.

В принципе: если пользователь не существует, создайте его и обновите значение. Если он существует, обновите значение.

Я правильно использую ON DUPLICATE? Могу ли я использовать WHERE при использовании ON DUPLICATE?

$sql = "INSERT INTO Users ('$column_name[$i]') VALUES ('$value[$i]') ON DUPLICATE KEY UPDATE '$column_name[$i]'='$value[$i]' WHERE LoginName = '$login_name'";

Ошибка, которую я получаю с этой строкой:

You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''record_id') VALUES ('5287469') ON DUPLICATE KEY UPDATE 'record_id' at line 1

Любые предложения о том, как я должен сформировать свой запрос?

  • 0
    Каково значение $ column_name [$ i]?
  • 0
    @SimonR Для этого примера это будет record_id , который существует в таблице.
Показать ещё 1 комментарий
Теги:

1 ответ

2
Лучший ответ

Предложение WHERE не может использоваться с оператором INSERT... VALUES.

Не имеет значения, что есть предложение ON DUPLICATE KEY или нет.

Справочное руководство MySQL показывает (загадочно), что в INSERT... VALUES нет WHERE:

https://dev.mysql.com/doc/refman/5.7/en/insert.html

(Оператор INSERT... SELECT может включать предложение WHERE в части SELECT оператора, как обычный SELECT.)


Не используйте одиночные кавычки вокруг идентификаторов (например, имена столбцов).

Если это нужно экранировать, используйте одиночные обратные символы.


Включение потенциально небезопасных значений в текст SQL бросает широко открытое целое множество неприятных уязвимостей, классифицированных как SQL Injection.

https://www.owasp.org/index.php/SQL_Injection

Это могут быть значения, которые включены в текст SQL, были надлежащим образом дезинфицированы или включены в белый список. Но мы не видим этого в коде, так что звонят тревожные звонки.


Нормативный шаблон (только SQL) будет примерно таким:

 INSERT INTO Users
 ( 'primary_or_unique_key_column' 
 , 'some_column_name' 
 ) VALUES 
 ( 'safe_unique_key_value'
 , 'safe_column_value'
 )
 ON DUPLICATE KEY
    UPDATE 'some_column_name' = VALUES('some_column_name')

Если LoginName является PRIMARY или UNIQUE KEY в таблице

 INSERT INTO Users
 ( 'loginname'
 , 'record_id' 
 ) VALUES 
 ( 'safe_loginname_value'
 , 'safe_record_id_value'
 )
 ON DUPLICATE KEY
    UPDATE 'record_id' = VALUES('record_id')

Обратите внимание, что использование обратных точек вокруг имен столбцов и одинарные кавычки вокруг буквенных строковых значений.

Также обратите внимание на использование функции VALUES, чтобы ссылаться на значение, которое было бы вставлено в столбец, если INSERT был успешным. (Избегает того, что мы должны предоставить такое же значение дважды.

Используя подготовленные операторы с заполнителями привязки, нам нужно будет правильно проверить имя столбца, которое будет включено в текст SQL (чтобы избежать уязвимостей SQL Injection... но значения могут быть переданы через заполнители.

Текст SQL будет выглядеть так:

 INSERT INTO Users
 ( 'loginname'
 , 'record_id' 
 ) VALUES 
 ( ?
 , ?
 )
 ON DUPLICATE KEY
    UPDATE 'record_id' = VALUES('record_id')

И код (предполагающий PDO) будет иметь вид:

$sth=$dbh->prepare($sql_text);
# check return from prepare

$sth->bindValue(1, $loginname_val, PDO::PARAM_STR);
$sth->bindValue(2, $record_id_val, PDO::PARAM_INT);

$sth->execute();
# check return from execute

Ещё вопросы

Сообщество Overcoder
Наверх
Меню