如果存在则更新SQL行,如果不存在则创建(在PHP中)

时间:2018-04-05 23:02:23

标签: php mysql

我试图在不知道用户是否存在的情况下为用户更新值。

基本上:如果用户不存在,请创建它,然后更新该值。如果确实存在,请更新该值。

我正确使用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

有关如何形成查询的任何建议?

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