2016-11-24 31 views
0

我正在使用pgnode.js。当用户使用auth0小部件登录时,我传递它返回的电子邮件并检查我的数据库以查看用户是否存在。如果用户不存在,我将它们插入到数据库中。我已经设法使这个工作与一个函数的黑客工作,但我会感谢一些帮助熨烫出来。处理Postgres错误消息以执行正确查询

我正面临的问题。

  1. 当检查数据库的电子邮件时,它没有检查整个电子邮件地址。

    var emailCheck = "SELECT id from public.user WHERE email=" + req.body.email;

    req.body.email;实际上是[email protected]

返回此错误,

column "myemail" does not exist 

即使

[email protected] 

确实存在。

  1. 无论它抛出的错误如何,它都会插入电子邮件地址。如果它不存在,则插入它。由于是在它抛出一个错误的电子邮件的唯一密钥

    重复键值违反唯一约束“uk_user_email”

因此,要解决这个问题,我的问题是为什么不检查的@符号后?我应该遵循什么逻辑来改变这个函数来运行第一个查询,并且只有在第一个查询没有找到有问题的电子邮件地址时才运行第二个查询?

checkRegister: function(req, res) { 
      pool.connect(function(err, client, done) { 
       if (err) { 
        return console.error('error fetching client from pool', err); 
       } connection 
       var emailCheck = "SELECT id from public.user WHERE email=" + req.body.email; 
       var emailInsert = "insert into public.user (user_auth_level,email,account_locked,contract) " + 
        "values ('1','" + req.body.email + "','false','false')" 
       client.query(emailCheck, function(err, result) { 
        if (err) { 
         return console.error(err.message); 
        } 

       }); 
       client.query(emailInsert, function(err, result) { 
        if (err) { 
         return console.error(err.message); 
        } 

       }); 
       done(); 
      }); 
      pool.on('error', function(err, client) { 
       console.error('idle client error', err.message, err.stack) 
      }); 
     } 

回答

1

你需要用'包装你的价值'来使它成为字符串。没有字符串换行,它将在列之间进行比较。它应该是:

var yourQuery = "SELECT id from public.user WHERE email=" + req.body.email; // SELECT id from public.user WHERE [email protected] 
var correntQuery = "SELECT id from public.user WHERE email='" + req.body.email + "'"; // SELECT id from public.user WHERE email='[email protected]' 

是的NodeJS同步,你需要使用回调或承诺链代码象下面这样:

checkRegister: function (req, res) { 
    pool.connect(function (err, client, done) { 
     if (err) { 
      console.error(err); 
      // should return response error like 
      return res.status(500).send(); 
     } 
     var emailCheck = "SELECT id from public.user WHERE email=$1"; 
     client.query(emailCheck, [req.body.email], function (err, result) { 
      if (err) { 
       console.error(err); 
       res.status(500).send(); 
       return done(); // always close connection 
      } 
      if (result.rowCount > 0) { 
       let user = result.rows[0] 
       // return your user 
       return done(); // always close connection 
      } else { 
       var emailInsert = "insert into public.user (user_auth_level, email, account_locked, contract) " + 
        "values ('1', $1,'false','false') RETURNING *" 
       client.query(emailInsert, [req.body.email], function (err, result) { 
        if (err) { 
         console.error(err); 
         res.status(500).send(); 
         return done(); // always close connection 
        } else { 
         if (result.rowCount > 0) { 
          let user = result.rows[0] 
          // return your user 
          return done(); // always close connection 
         } 
        } 

       }); 
      } 
     }) 
    }) 
    pool.on('error', function (err, client) { 
     console.error('idle client error', err.message, err.stack) 
    }); 
} 
+0

谢谢。这是超级有用的。超越和超越。 – wuno

+0

我的另一个2分,总是更好地使用准备语句,而不是concat查询字符串更好的安全性和控制,如自动转义和数据类型检测。请参阅我上面更新的回答 – Simon

+0

谢谢我一直在阅读关于此的2小时。 – wuno

1

对于#1,问题是您没有引用您的输入值。既然(我认为)你可能不想担心引用/转义/等你自己的价值观,我会考虑使用parameterized queries。这将有助于防止SQL注入(并且您当前的代码非常容易接触到这一点)。

对于#2,它实际上并不“抛出”该错误。该方法是异步的,并向回调提供错误。如果你想运行“以”查询,你需要做这样的事情:

client.query(emailCheck, function(err, result) { 
    if (err) { 
    // should probably do `return done(err);` here 
    return console.error(err.message); 
    } 
    client.query(emailInsert, function(err, result) { 
    if (err) { 
     // same thing - probably need done(err) in here 
     return console.error(err.message); 
    } 
    return done(); 
    }); 
}); 

注意呼叫的方式嵌入到每一个其他的“内部”(内回调,特别是)。

+0

嘿由于一吨!这一直在杀死我。我不明白你的意思第一。它插入完整的电子邮件就好了。为什么不检查整个电子邮件?我没有看到检查是否存在并插入它们之间有什么区别。 – wuno

+0

哦,在你的'check'查询中,你不会在你的电子邮件中加上单引号'',所以postgres的查询解析器会出错。那是第一个错误来自哪里。 – dvlsg