SQL WHERE NOT EXISTS with string conditional

问题描述

我正在尝试使用如下子查询检查我的数据库MysqL、Node.js)中是否不存在电子邮件

register: async (data) => {

const rows = await db.promise().execute(

INSERT INTO Users (userEmail,userPassword) 
    SELECT * 
    FROM 
        (SELECT ${data.userEmail},${data.userPassword}) AS tmp
    WHERE 
        NOT EXISTS (SELECT userEmail,userPassword 
                    FROM Users 
                    WHERE userEmail = {data.userEmail}) 
    LIMIT 1;

 );
      return rows;
    },

但它不起作用

我已经在尝试使用 ID 类型为 INT 的请求。

我的问题是:你认为这个请求可以使用字符串类型吗?

非常感谢!

如果我向已在我的数据库注册用户发出请求,我会收到此错误

{

"error": {
    "message": "You have an error in your sql Syntax; check the manual that corresponds to your MysqL server version for the right Syntax to use near '@beevora.fr,$2b$10$JnEjg8GIVXbJDAeGnm7ESey27yXkHMcvh2b/SKRQ.6UH5Tpvv.OVG\n      ' at line 2","code": "ER_PARSE_ERROR","errno": 1064,"sqlState": "42000","sqlMessage": "You have an error in your sql Syntax; check the manual that corresponds to your MysqL server version for the right Syntax to use near '@beevora.fr,$2b$10$JnEjg8GIVXbJDAeGnm7ESey27yXkHMcvh2b/SKRQ.6UH5Tpvv.OVG\n      ' at line 2"
},"errMessage": "500 error server"

}##

如果用户还不存在:

{

"error": {
    "message": "UnkNown column 'Lorris' in 'field list'","code": "ER_BAD_FIELD_ERROR","errno": 1054,"sqlState": "42S22","sqlMessage": "UnkNown column 'Lorris' in 'field list'"
},"errMessage": "500 error server"

}##

解决方法

是的,这是可能的,并且不取决于您的类型 - 字符串或整数。它与 int 一起使用,因为您发送查询:

select 1 

对于 sql 意味着必须插入 1 作为 int 类型 如果您设置字符串,您可以像这样将查询发送到数据库选择:

select mymail@gmail.com 

数据库理解名为 mymail@gmail.com 的选择列应该搜索列 mymail@gmail.com - 它没有找到任何列。

正确的是:

 select 'mymail@gmail.com'

用''

但是将来自用户的原始值插入到查询中是错误的 - 您将具有 SQL 注入漏洞,任何熟悉此注入的人都可以访问任何数据并将任何内容插入到您的数据库中。您可以在 SQL Injection wikipedia

阅读更多信息

为了使其正常工作,您应该

  1. 在电子邮件上创建具有唯一约束的表,如下所示
CREATE TABLE users (
  id INT PRIMARY KEY AUTO_INCREMENT,email VARCHAR(256) NOT NULL UNIQUE,password_hash VARCHAR(256)
)

您需要 id 来引用其他表,我建议您不要存储原始密码,而是存储哈希(例如 sha-1),以防止在访问您的数据库时窃取密码 2. 像这样查询

dbconn.query("INSERT INTO USERS (email,password_hash) VALUES (?,?)",[email,passwordHash],(err,result) => {
 if(err){
   //1169 or 1062 error code. See error reference below
   if(err.code == DUPLICATE_ERROR_CODE){ 
     notifyUserThatEmailExists();
     return;
   } else {
     throw err;
   }
   success();
 } 
}

Error Reference MySQL

在这个例子中,email 和密码哈希参数将被设置为参数,并且总是被数据库解释为参数,而不是列名,并且这个查询将被保护免受 SQL 注入