Node.js 使用准备好的语句参数pg promise按命令排序
我不熟悉节点、API和SQL,我遇到了麻烦。我正在使用Node.js 使用准备好的语句参数pg promise按命令排序,node.js,postgresql,pg-promise,Node.js,Postgresql,Pg Promise,我不熟悉节点、API和SQL,我遇到了麻烦。我正在使用pg promise准备好的语句,并尝试使用sorted参数和ORDERED BY命令对结果进行常规排序,但它不起作用,因为总是按相同的顺序排序。 如果我直接使用参数的名称,它会起作用,您能看到我的查询有什么问题吗? 像往常一样,非常感谢您的时间和帮助。 这是我的方法: if (city, region, country, category, minPrice, maxPrice, orderedBy, sorted) { if (s
pg promise
准备好的语句,并尝试使用sorted
参数和ORDERED BY
命令对结果进行常规排序,但它不起作用,因为总是按相同的顺序排序。
如果我直接使用参数的名称,它会起作用,您能看到我的查询有什么问题吗?
像往常一样,非常感谢您的时间和帮助。
这是我的方法:
if (city, region, country, category, minPrice, maxPrice, orderedBy, sorted) {
if (sorted == 'asc') {
await db.any({
name: 'get-city-category-price-range-ordered-by-asc-products',
// text: 'SELECT * FROM products WHERE city = $1 AND region = $2 AND country = $3 AND category = $4 AND price >= $5 AND price <= $6 ORDER BY price ASC', // working
text: 'SELECT * FROM products WHERE city = $1 AND region = $2 AND country = $3 AND category = $4 AND price >= $5 AND price <= $6 ORDER BY $7 ASC', // not working
values: [city, region, country, category, minPrice, maxPrice, orderedBy]
})
.then(result => {
console.log('get-city-category-price-range-ordered-by-asc-products:', result);
if (result.length > 0) {
res.status(200).send({
data: result
});
}
else {
res.status(404).send({
error: 'No product found.'
});
}
})
.catch(function (error) {
console.log('get-city-category-price-range-ordered-by-asc-products error:', error);
});
} else if (sorted == 'desc') {
await db.any({
name: 'get-city-category-price-range-ordered-by-desc-products',
// text: 'SELECT * FROM products WHERE city = $1 AND region = $2 AND country = $3 AND category = $4 AND price >= $5 AND price <= $6 ORDER BY price DESC', // working
text: 'SELECT * FROM products WHERE city = $1 AND region = $2 AND country = $3 AND category = $4 AND price >= $5 AND price <= $6 ORDER BY $7 DESC', // not working
values: [city, region, country, category, minPrice, maxPrice, orderedBy]
})
.then(result => {
console.log('get-city-category-price-range-ordered-by-desc-products:', result);
if (result.length > 0) {
res.status(200).send({
data: result
});
}
else {
res.status(404).send({
error: 'No product found.'
});
}
})
.catch(function (error) {
console.log('get-city-category-price-range-ordered-by-desc-products error:', error);
});
}
}
if(城市、地区、国家、类别、最低价格、最高价格、订购人、排序){
如果(排序==“asc”){
等待db.any({
名称:“获取asc产品订购的城市类别价格范围”,
//text:'SELECT*FROM products,其中city=$1,region=$2,country=$3,category=$4,price>=$5,price=$5,price=$5,price不幸的是,您不能对列和表名之类的东西使用查询参数,只能对值使用。因此这永远不会起作用,您需要手动通过添加正确的“order by”语句。所有关于SQL注入的警告都将应用,因此请检查您的order by字段是否有效(例如,仅包含字母、无空格或其他字符).当您选择时,您的查询格式是在服务器端完成的。因此,如果您决定正是出于此目的而使用,以获得服务器格式化的值,那么您将不得不使用内部支持常规查询的丰富查询格式,并将自己限制在PostgreSQL server在这方面的功能范围内。以及与之不同,PostgreSQL server不允许在任何地方使用动态SQL名称或标识符
但是,如果您的选择是因为您认为在您的情况下它会执行得更快,那么您仍然可以受益于pg promise
支持的丰富的查询格式,方法是单独格式化查询,然后使用预格式化查询执行,即不使用任何参数:
const text=pgp.as.format(`SELECT*FROM products,其中city=$/city/
地区=$/地区/和国家=$/国家/
和类别=$/类别/
价格介于$/minPrice/和$/maxPrice/之间/
ORDER BY$/orderedBy:name/$/sorted:value/`{
城市、地区、国家、类别,
minPrice、maxPrice、orderedBy、排序
});
const name='get price range ordered by products-'+sorted;//唯一查询名称
等待db.any({name,text});
如您所见,排序顺序也可以动态设置,无需复制代码。我们将排序
附加到查询的名称
,因为它生成不同的执行路径,需要唯一的查询名称
另外,我是。的作者,谢谢您的回答。因为我只有3个order by案例,所以我可以实现一个开关来检查'orderedBy'查询参数并形成正确的SQL文本,这对SQLI足够安全吗?是的,只从常量字符串而不是用户的字符串生成SQL更安全。确定吗,orderedBy参数(与其他参数一样)是从下拉菜单中选择的。只有产品创建才有用户输入,但是pg promise
和准备好的语句会处理SQLi的转义,对吗?再次感谢您的帮助。实际上,我选择它是为了SQLi保护,而不是为了执行速度,(你这么问是因为PreparedStatements很慢?我看到了性能提升的文章)。事实上,我正在经历一些代码重复,因为我刚刚开始,并围绕sql概念和pg承诺进行思考,所以有时我可能会选择更详细的方法,并在我进行过程中重构代码,就像本例中的format
方法一样。再次感谢库。我确实收到了一个错误必须准备好的语句在排序属性中将ASC
替换为DESC
时,请保持唯一,并再次运行请求。这是因为不同的排序顺序在服务器上内部创建了不同的查询路径,但您给了它相同的名称,因此服务器引发了错误。请参阅我更新了答案,将sorted
附加到t查询的名称
的结尾。事实上,我碰巧遇到了旧代码,我尝试将其插入字符串中,如get city category price range ordering by-${orderedBy}-${sorted}-产品
或但不起作用,因为替换失败,因为知道类型。.追加确实起到了最后的作用。您不能使用{}
在ES6模板字符串内进行查询。