代码之家  ›  专栏  ›  技术社区  ›  snoob dogg

es5格式化长sql查询的方法

  •  1
  • snoob dogg  · 技术社区  · 7 年前

    使用google apps脚本,我有一些很长的sql查询,如下所示:

    var query = "SELECT od.`product_reference`, od.`product_name`, SUM(od.`product_quantity`) AS 'cpt' " +
        "FROM `ps_order_detail` od " +
        "JOIN `ps_orders` o ON o.`id_order` = od.`id_order` " +
        "WHERE od.`product_reference` NOT LIKE ('%GIFT%') " +
        "AND o.`date_add` BETWEEN " + dateDeb + " AND " + dateFin + " " +
        "GROUP BY `product_id` " +
        "ORDER BY cpt DESC " +
        "LIMIT 10;";
    

    我觉得很难看,你知道如何更好地格式化这些查询吗?知道google apps脚本提供了ecma 5的一个子集吗?

    3 回复  |  直到 7 年前
        1
  •  2
  •   Alex Pappas    7 年前

    不幸的是,由于您仅限于使用ecma 5,最短/最佳的方法是 + 是的。你可以这样安排 @Sergey Podgornyy 的 answer 让它看起来更整洁。

    但如果你只是想避免使用 + 这个想法是利用 评论 它的处理和使用如下所示。我们传递一个函数作为方法的第一个参数 multipleLineString . 该函数被解析为字符串,字符串中包含注释。如果你足够小心,你可以做以下工作:

    var multipleLineString = function(f) {
        return f.toString().split('\n').slice(1, -1).join('\n');
    }
    
    var sqlQuery = multipleLineString (function() {/**
    First Line
    'Second' Line
    "Third" Line (3)
    **/});
    

    但就你而言,你的价值观来自 dateDeb 和 dateFin 在查询中插入。你可以把这个扩展到像这样的东西:

    var multiLine = function (f, dictionary) {
        var compiledString = f.toString().split('\n').slice(1, -1).join('\n');
        for (var key in dictionary) {
            compiledString = compiledString.replace(new RegExp(key, 'g'), dictionaty[key].toString());
        }
        // Add other enhancements before return (e.g. trimming & cleaning multiple white spaces)
        return compiledString;
    }
    
    var query = multiLine (function() {/**
        SELECT od.`product_reference`, od.`product_name`, SUM(od.`product_quantity`) AS 'cpt' 
        FROM `ps_order_detail` od 
        JOIN `ps_orders` o ON o.`id_order` = od.`id_order` 
        WHERE od.`product_reference` NOT LIKE ('%GIFT%') 
        AND o.`date_add` BETWEEN _dateDeb AND _dateFin 
        GROUP BY `product_id` 
        ORDER BY cpt DESC 
        LIMIT 10;
        **/},
        {
            _dateDeb: dateDeb,
            _dateFin: dateFin
        }
    );
    

    以上解释:第二个论点, dictionary ,是一种“键值对”对象,以便我们可以在注释中定义关键字( _dateDeb 和 _dateFin )从第一个参数及其对应的值被替换。和C一样 Dictionary . 但是由于js不是强类型的,所以在构建对象时必须小心。确保正确地/相应地构建了第二个参数,并且第一个参数是一个类似于上述示例的函数。

        2
  •  1
  •   Sergey Podgornyy    7 年前

    如果您只想用es6格式化这个字符串,那么最好的方法可能是“template string”:

    const query = `
      SELECT 
        od.product_reference,
        od.product_name,
        SUM(od.`product_quantity`) AS 'cpt'
      FROM ps_order_detail od 
      JOIN ps_orders o ON o.id_order = od.id_order
      WHERE
        od.product_reference NOT LIKE ('%GIFT%')
        AND o.date_add BETWEEN ${dateDeb} AND ${dateFin}
      GROUP BY product_id
      ORDER BY cpt DESC
      LIMIT 10;
    `;
    

    如果需要支持ES5:

    var query = ''
      + 'SELECT '
      + '  od.product_reference, '
      + '  od.product_name, '
      + '  SUM(od.`product_quantity`) AS \'cpt\' '
      + 'FROM ps_order_detail od '
      + 'JOIN ps_orders o ON o.id_order = od.id_order '
      + 'WHERE '
      + '  od.product_reference NOT LIKE (\'%GIFT%\') '
      + '  AND o.date_add BETWEEN ' + dateDeb + ' AND ' + dateFin + ' '
      + 'GROUP BY product_id '
      + 'ORDER BY cpt DESC '
      + 'LIMIT 10;';
    
        3
  •  -1
  •   TheAddonDepot    7 年前

    如果您使用的是mysql,则可以使用存储过程。存储过程是存储在数据库服务器中的命名、参数化查询。部署完存储过程后,只需使用适当的参数调用该过程。