参数化查询不会读入(使用express和postgresql)

问题描述 投票:0回答:1

这里完全是菜鸟,

我正在尝试重构我的端点,以允许通过设置为默认值的变量“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
            })
    }
}

我已经控制台记录了传入的两个值,它们是正确的,我尝试了使用上述值的各种语法,例如通过字符串横向将两个值组合成一个字符串。

node.js postgresql express prepared-statement
1个回答
0
投票

您的问题似乎与 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”替换为您希望允许排序的实际列名称。此方法可确保查询中仅使用有效的列名称和排序顺序。

© www.soinside.com 2019 - 2024. All rights reserved.