我试图在不知道用户是否存在的情况下为用户更新值。
基本上:如果用户不存在,请创建它,然后更新该值。如果确实存在,请更新该值。
我正确使用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 :(得分:2)
WHERE
子句不能与INSERT ... VALUES
语句一起使用。
是否有ON DUPLICATE KEY
条款并不重要。
MySQL参考手册(以一种神秘的方式)揭示WHERE
语句中没有INSERT ... VALUES
子句:
https://dev.mysql.com/doc/refman/5.7/en/insert.html
(INSERT ... SELECT
语句可以在语句的WHERE
部分中包含SELECT
子句,就像普通的SELECT
语句一样。)
请勿在标识符周围使用单引号(例如列名称)。
如果需要转义,请使用单个反引号字符。
在SQL文本中包含可能不安全的值会引发大量令人讨厌的漏洞,分类为SQL注入。
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`)
请注意在列名称周围使用反引号,并在文字字符串值周围使用单引号。
如果INSERT成功,还要注意VALUES
函数的用法,以引用插入到列中的值。 (避免我们必须提供两次相同的值。
使用带有绑定占位符的预准备语句,我们需要正确验证要合并到SQL文本中的列名(以避免SQL注入漏洞......但值可以通过占位符。
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