Node.js 使用准备好的语句参数pg promise按命令排序

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

我不熟悉节点、API和SQL,我遇到了麻烦。我正在使用
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模板字符串内进行查询。