Javascript Node API 构建 SQL 查询的最佳方式

标签 javascript sql-server node.js

我正在用 JS 构建一个在 Node 上运行的简单 API。它连接到 MS SQL 数据库以获取文章并将其作为 JSON 返回。一切都很完美,但我觉得我可以更简单地编写查询。

目前我有几个 if 语句。有没有办法使查询动态化,这样我就不必为每个查询都添加 if 语句?

...

app.get('/articles', function (req, res) {

    // Our URL parameters
    var articles = req.query.articles;
    var countryID = req.query.countryID;
    var offset = req.query.offset;

    // Set up the database connection
    var connection = new sql.Connection(db_config, function(err) {

        // Log any errors to the console
        if (err) console.log(err);

        // Connect using prepared statement
        var ps = new sql.PreparedStatement(connection);

        // Our variable is an Int
        ps.input('articles', sql.Int);
        ps.input('countryID', sql.Int);
        ps.input('offset', sql.Int);
        ps.input('live', sql.VarChar(5));

        // Build the query and pass in the parameters

        // @articles, @countryID and @offset are empty
        if (isEmpty(articles) && isEmpty(countryID) && isEmpty(offset)) {
            var query = 'SELECT TOP 15 * FROM dbo.articlesCountryTown WHERE articleLive = (@live) ORDER BY PublishDate DESC';
            //console.log('Using query 1');

        // @articles and @offset are empty, @countryID is present
        } else if (isEmpty(articles) && countryID && isEmpty(offset)) {
            var query = 'SELECT TOP 15 * FROM dbo.articlesCountryTown WHERE CntryId = (@countryID) AND articleLive = (@live) ORDER BY PublishDate DESC';
            //console.log('Using query 2');

        // @articles is present, @countryID and @offset are empty
        } else if (articles && isEmpty(countryID) && isEmpty(offset)) {
            var query = 'SELECT TOP (@articles) * FROM dbo.articlesCountryTown WHERE articleLive = (@live) ORDER BY PublishDate DESC';
            //console.log('Using query 3');

        // @articles and @countryID are empty, @offset is present
        } else if (isEmpty(articles) && isEmpty(countryID) && offset) {
            var query = 'SELECT TOP 15 * FROM (select *, ROW_NUMBER() OVER (ORDER BY PublishDate DESC) as r_n_n from dbo.articlesCountryTown WHERE articleLive = (@live)) xx WHERE r_n_n >= (@offset + 1)';
            //console.log('Using query 4');

        // @articles and @countryID are present, @offset is empty
        } else if (articles && countryID && isEmpty(offset)) {
            var query = 'SELECT TOP (@articles) * FROM dbo.articlesCountryTown WHERE CntryId = (@countryID) AND articleLive = (@live) ORDER BY PublishDate DESC';
            //console.log('Using query 5');

        // @articles and @offset are present, @countryID is empty
        } else if (articles && isEmpty(countryID) && offset) {
            var query = 'SELECT TOP (@articles) * FROM (select *, ROW_NUMBER() OVER (ORDER BY PublishDate DESC) as r_n_n from dbo.articlesCountryTown WHERE articleLive = (@live)) xx WHERE r_n_n >= (@offset + 1)';
            //console.log('Using query 6');

        // @articles, @countryID and @offset are all present
        } else {
            var query = 'SELECT TOP (@articles) * FROM (select *, ROW_NUMBER() OVER (ORDER BY PublishDate DESC) as r_n_n from dbo.articlesCountryTown WHERE CntryId = (@countryID) AND articleLive = (@live)) xx WHERE r_n_n >= (@offset + 1)';
            //console.log('Using query 7');
        }

        // Prepare the query
        ps.prepare(query, function(err) {
            // Log any errors to the console
            if (err) console.log(err);

            // Pass in the parameters and execute the query
            ps.execute({articles: req.query.articles, countryID: req.query.countryID, offset: req.query.offset, live: 'true'}, function(err, recordset) {
                // Return the JSON
                res.json(recordset);

                // Close the connection
                ps.unprepare(function(err) {
                    // Log any errors to the console
                    if (err) console.log(err);
                });
            });
        });
    });
});

...

最佳答案

如果您能够将 null 值传递给 @articles、@countryId 和 @offset,那么只需一个查询就可以了:

SELECT TOP (ISNULL(@articles, 15)) * FROM (
    SELECT *, ROW_NUMBER() OVER (ORDER BY PublishDate DESC) as r_n_n from dbo.articlesCountryTown 
    WHERE CntryId = CASE WHEN @countryId IS NULL THEN CntryId ELSE @countryId END
    AND articleLive = (@live)
) xx 
WHERE r_n_n >= (ISNULL(@offset, 0) + 1)

更好的是,将其包装到参数默认为 null 的存储过程中。使用存储过程总是比在服务器级别使用字符串更好。

关于Javascript Node API 构建 SQL 查询的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41588275/

相关文章:

sql - 数据库修改脚本 - 推出/回滚最佳实践?

javascript - 如何使用 rewirejs 和 chai-spies 模拟函数来测试它?

javascript - 在 Electron 中禁用缩放(双指缩放和智能缩放 [mac])

javascript - 按值对对象属性进行排序

sql-server - 没有 SSL 证书的 SQL Server 2012 ForceEncryption?

c# - SQL Server 和 C# 之间的性能问题

node.js - 在package.json中运行另一个yarn/npm任务,而不指定yarn或npm

node.js - 当 mongodb 发生变化时更新客户端中的位置

Javascript 每次循环 JSON 时只获取第一个元素?

javascript - 在使用来自深度 npm 依赖项的构造函数创建的对象上使用 `instanceof`