这里完全是菜鸟,
我正在尝试重构我的端点,以允许通过设置为默认值的变量“sort_by”和“order”读取的几列对返回表进行排序,但是在运行测试时,它会返回一个无序数组。我已经通过 postgresql 终端手动尝试了该命令,所以我知道语法是正确的,问题是当尝试将变量作为参数插入到express中时,它就像忽略了 ORDER BY 行,我不太确定为什么我有类似的端点,使用按预期工作的相同函数,我能看到的唯一区别是,在这种情况下,值不在 = 符号之前。任何指示都将是天赐之物,因为这正在成为我的项目的一大障碍。
我的技术栈是:
"pg-promises": "^8.7.3"
"express": "^4.18.2",
"postgresql" : ^14.10
使用以下命令和功能:
return request(app).get("/api/articles")
exports.fetchAllArt = (sort_by = 'created_at',order = 'DESC')=>{
return db.query(
`SELECT
articles.article_id,
articles.author,
articles.title,
articles.topic,
articles.created_at,
articles.votes,
articles.article_img_url,
COUNT(comments.article_id) AS comment_count
FROM articles
LEFT JOIN comments
ON articles.article_id = comments.article_id
GROUP BY articles.article_id
ORDER BY ($1), ($2)`,[sort_by, order]
).then(({rows})=>{
return rows
})
}
}
我已经控制台记录了传入的两个值,它们是正确的,我尝试了使用上述值的各种语法,例如通过字符串横向将两个值组合成一个字符串。
您的问题似乎与 SQL 如何处理准备好的语句中的参数有关,特别是在使用 ORDER BY 进行动态排序的上下文中。在 PostgreSQL 中,当您在查询中使用参数(如 $1、$2)时,它们将被视为文字值,而不是标识符或关键字。这意味着您的 ORDER BY ($1), ($2) 子句没有按照您的预期进行解释;它将它们视为字符串文字,而不是使用 sort_by 和 order 的内容作为列名称和排序方向。
为了解决这个问题,您需要动态构建 SQL 查询以包含正确的列名称和排序顺序。但是,应谨慎处理此方法,以避免 SQL 注入漏洞。由于 pg-promise 支持命名参数,因此您可以安全地构造查询,如下所示:
exports.fetchAllArt = (sort_by = 'created_at', order = 'DESC') => {
// Construct the query with the validated parameters
const query = `
SELECT
articles.article_id,
articles.author,
articles.title,
articles.topic,
articles.created_at,
articles.votes,
articles.article_img_url,
COUNT(comments.article_id) AS comment_count
FROM articles
LEFT JOIN comments
ON articles.article_id = comments.article_id
GROUP BY articles.article_id
ORDER BY ${sort_by} ${order}`;
return db.query(query).then(({ rows }) => {
return rows;
});
}
在此重构函数中,sort_by 和 order 会动态插入到查询字符串中,但前提是针对允许值列表进行验证。此验证步骤对于防止 SQL 注入攻击至关重要。
请记住将“column1”、“column2”替换为您希望允许排序的实际列名称。此方法可确保查询中仅使用有效的列名称和排序顺序。