Node.js 处理Postgres错误消息以执行正确的查询
我正在使用pg和node.js。当用户使用auth0小部件登录时,我正在传递它返回的电子邮件,并检查我的数据库以查看该用户是否存在。如果用户不存在,我将把他们插入数据库。我已经设法让这与一个函数的黑客工作,但我会感谢一些帮助熨烫出来 我面临的问题 在检查数据库中的电子邮件时,它并不是在检查整个电子邮件地址 var emailCheck=从public.user中选择id,其中email=+req.body.email req.body.email;实际上是myemail@example.com 返回此错误Node.js 处理Postgres错误消息以执行正确的查询,node.js,postgresql,angular,node-postgres,Node.js,Postgresql,Angular,Node Postgres,我正在使用pg和node.js。当用户使用auth0小部件登录时,我正在传递它返回的电子邮件,并检查我的数据库以查看该用户是否存在。如果用户不存在,我将把他们插入数据库。我已经设法让这与一个函数的黑客工作,但我会感谢一些帮助熨烫出来 我面临的问题 在检查数据库中的电子邮件时,它并不是在检查整个电子邮件地址 var emailCheck=从public.user中选择id,其中email=+req.body.email req.body.email;实际上是myemail@example.com
column "myemail" does not exist
即使
myemail@example.com
确实存在
不管它抛出什么错误,它都会继续插入电子邮件地址。如果不存在,则将其插入。因为电子邮件上有一个唯一的密钥,所以会抛出一个错误
重复的键值违反了唯一约束uk\u用户\u电子邮件
所以要解决这个问题,我的问题是为什么它不在@符号后检查?我应该遵循什么逻辑来更改此函数,以运行第一个查询,并且仅在第一个查询未找到相关电子邮件地址时运行第二个查询
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,问题是您没有引用输入值。因为我假设您可能不想担心引用/转义/等您自己的值,所以我会考虑使用。这将有助于防止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();
});
});
请注意调用是如何嵌入在回调中的。具体来说,对于1,问题是您没有引用输入值。因为我假设您可能不想担心引用/转义/等您自己的值,所以我会考虑使用。这将有助于防止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();
});
});
请注意这些调用是如何嵌入到回调中的,特别是。您需要用“将值包装为字符串”。如果没有字符串换行,它将在列之间进行比较。应该是:
var yourQuery = "SELECT id from public.user WHERE email=" + req.body.email; // SELECT id from public.user WHERE email=myemail@example.com
var correntQuery = "SELECT id from public.user WHERE email='" + req.body.email + "'"; // SELECT id from public.user WHERE email='myemail@example.com'
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)
});
}
您需要使用“将值包装为字符串”。如果没有字符串换行,它将在列之间进行比较。应该是:
var yourQuery = "SELECT id from public.user WHERE email=" + req.body.email; // SELECT id from public.user WHERE email=myemail@example.com
var correntQuery = "SELECT id from public.user WHERE email='" + req.body.email + "'"; // SELECT id from public.user WHERE email='myemail@example.com'
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)
});
}
嘿,非常感谢!这让我很痛苦。我不明白你说的第一是什么意思。它可以插入完整的电子邮件。为什么不检查整个电子邮件?我不明白检查它是否存在和插入它之间有什么区别。哦,在你的检查查询中,你没有在你的电子邮件周围加上单引号,所以postgres的查询解析器出错了。这就是第一个错误的来源。嘿,非常感谢!这让我很痛苦。我不明白你说的第一是什么意思。它可以插入完整的电子邮件。为什么不检查整个电子邮件?我不明白检查它是否存在和插入它之间有什么区别。哦,在你的检查查询中,你没有在你的电子邮件周围加上单引号,所以postgres的查询解析器出错了。这就是第一个错误的来源。我的另一个2美分,最好使用prepared语句而不是concat查询字符串,以获得更好的安全性和控制,如自动转义和数据类型检测。参考我上面更新的答案,如果我要添加5个值,请您向我解释$1,它是否知道$1是第一个变量项,如果有第二个变量项,请使用$2?如果不是这样的话,那该怎么做呢?我的另一个2美分,总是最好使用prepared语句而不是concat查询字符串,以获得更好的安全性和控制,比如自动转义和数据类型检测。参考我上面更新的答案,如果我要添加5个值,请您向我解释$1,它是否知道$1是第一个变量项,如果有第二个变量项,请使用$2?如果不是这样的话,那怎么办?