Я пытаюсь обновить значение для пользователя, не зная, существует ли пользователь или нет.
В принципе: если пользователь не существует, создайте его и обновите значение. Если он существует, обновите значение.
Я правильно использую 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
Любые предложения о том, как я должен сформировать свой запрос?
Предложение 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
record_id
, который существует в таблице.