处理 Postgres 错误消息以执行正确的查询
Handling Postgres Error Message To Perform Correct Query
我正在使用 pg
和 node.js
。当用户使用 auth0
小部件登录时,我将电子邮件传递给它 returns 并检查我的数据库以查看该用户是否存在。如果用户不存在,我将把它们插入到数据库中。我已经设法通过一个函数的 hack 工作来完成这项工作,但我希望能得到一些帮助来解决这个问题。
我面临的问题。
当检查数据库中的电子邮件时,它并没有检查整个电子邮件地址。
var emailCheck = "SELECT id from public.user WHERE email=" + req.body.email;
req.body.email;
其实就是myemail@example.com
Returns这个错误,
column "myemail" does not exist
尽管
myemail@example.com
确实存在。
不管它抛出什么错误,它都会继续插入电子邮件地址。如果不存在,则将其插入。由于电子邮件中有唯一键,因此会引发错误
重复键值违反唯一约束"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,问题是您没有引用您的输入值。因为(我假设)你可能不想担心引用/转义/等等你自己的价值观,我会考虑使用 parameterized queries。这将有助于保护您免受 sql 注入(并且您当前的代码很容易受到这种影响)。
对于 #2,它实际上 "throw" 不是那个错误。该方法是异步的,并将错误提供给回调。如果你想 运行 查询 "in order",你需要做这样的事情:
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();
});
});
注意这些调用是如何相互嵌入 "inside" 的(特别是在回调内部)。
您需要用 ' 包裹您的值以使其成为字符串。如果没有字符串换行,它将在列之间进行比较。应该是:
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=";
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', ,'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)
});
}
我正在使用 pg
和 node.js
。当用户使用 auth0
小部件登录时,我将电子邮件传递给它 returns 并检查我的数据库以查看该用户是否存在。如果用户不存在,我将把它们插入到数据库中。我已经设法通过一个函数的 hack 工作来完成这项工作,但我希望能得到一些帮助来解决这个问题。
我面临的问题。
当检查数据库中的电子邮件时,它并没有检查整个电子邮件地址。
var emailCheck = "SELECT id from public.user WHERE email=" + req.body.email;
req.body.email;
其实就是myemail@example.com
Returns这个错误,
column "myemail" does not exist
尽管
myemail@example.com
确实存在。
不管它抛出什么错误,它都会继续插入电子邮件地址。如果不存在,则将其插入。由于电子邮件中有唯一键,因此会引发错误
重复键值违反唯一约束"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,问题是您没有引用您的输入值。因为(我假设)你可能不想担心引用/转义/等等你自己的价值观,我会考虑使用 parameterized queries。这将有助于保护您免受 sql 注入(并且您当前的代码很容易受到这种影响)。
对于 #2,它实际上 "throw" 不是那个错误。该方法是异步的,并将错误提供给回调。如果你想 运行 查询 "in order",你需要做这样的事情:
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();
});
});
注意这些调用是如何相互嵌入 "inside" 的(特别是在回调内部)。
您需要用 ' 包裹您的值以使其成为字符串。如果没有字符串换行,它将在列之间进行比较。应该是:
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=";
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', ,'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)
});
}