繁体   English   中英

如何使用父子值从多维数组值生成字符串? - 动态 SQL 查询生成器

[英]How to make string from multidimential array values using parent child values ? - Dynamic SQL query generator

这是动态数组数据。 我在下面提到了我需要生成SQL查询的示例数据

我使用 VueJs + Laravel。 下面我更新了数组数据和方法

[
  {
    "operator": "AND",
    "rules": [
      {
        "id": 100,
        "column": "dd_Tttp",
        "type": "equal",
        "value": true,

        "join": "AND",
      }
    ],
    "groups": [
      {
        "operator": "AND",
        "rules": [
          {
            "id": 200,
            "column": "dd_tering",
            "type": "equal",
            "value": true,

            "join": "AND",

          },
          {
            "id": 201,
            "column": "dd_Size",
            "type": "in",
            "value": "Standard",

            "join": "AND",

          },
          {
            "id": 202,
            "column": "dd_Lotpth",
            "type": "equal",
            "value": "12",

            "join": "AND",

          }
        ],
        "groups": [
          {
            "operator": "AND",
            "rules": [

              {
                "id": 300,
                "column": "dd_cat",
                "type": "equal",
                "value": "34",

                "join": "AND",

              },
              {
                "id": 301,
                "column": "dd_Cot",
                "type": "in",
                "value": "Coftlassic",

                "join": "AND",

              },
              {
                "id": 302,
                "column": "dd_dse",
                "type": "equal",
                "value": "2020-01-01",

                "join": "AND",

              },
              {
                "id": 303,
                "column": "dd_turflaid",
                "type": "equal",
                "value": true,

                "join": "AND",

              }
            ],
            "groups": [

            ]
          }
        ]
      }
    ]
  },
  {
    "operator": "AND",
    "rules": [

      {
        "id": 100,
        "column": "dd_get",
        "type": "equal",
        "value": true,

        "join": "AND",
      },
      {
        "id": 101,
        "column": "dd_ccc",
        "type": "in",
        "value": "Standard",

        "join": "AND",
      }
    ],
    "groups": [

    ]
  }
]

将上面的数组数据传递给这个函数我想像这样出去

(dd_Tttp = 'true' (dd_tering = 'true' AND dd_Size IN ('Standard') AND dd_Lotpth = '12' AND (dd_cat = '34' AND dd_Cot IN ('Coftlassic') AND dd_dse = '2020-01-01' AND dd_turflaid = 'true'))) AND (dd_get = 'true' AND dd_ccc IN ('Standard'))



groupQueryGen(groups){

   let self = this;
   let join = ''; 
   let gggg = '';

  $.each(groups, function(key, group) {

        gggg = self.groupQueryGen(group.groups);
       //console.log('group',gggg);
       join = self.ruleQueryGen(group.rules);


       join += join + '( '+gggg+' )';
    });


    return join ;

}

ruleQueryGen(rules){
    let join = '';
    $.each(rules, function(index, value) {
        if(value)
        {
            if(value.type == 'equal'){
                join += value.colum+" = '"+ value.value+"' "+value.join+" ";
            }else if(value.type == 'not_equal'){
                join += value.colum+" != '"+ value.value+"' "+value.join+" ";
            }else if(value.type == 'in'){
                join += value.colum+" IN ('"+ value.value+"') "+value.join+" ";
            }else if(value.type == 'not_in'){
                join += value.colum+" NOT IN ('"+ value.value+"') "+value.join+" ";
            }else if(value.type == 'less'){
                join += value.colum+" < '"+ value.value+"' "+value.join+" ";
            }else if(value.type == 'less_or_equal'){
                join += value.colum+" <= '"+ value.value+"' "+value.join+" ";
            }else if(value.type == 'greater'){
                join += value.colum+" > '"+ value.value+"' "+value.join+" ";
            }else if(value.type == 'greater_or_equal'){
                join += value.colum+" >= '"+ value.value+"' "+value.join+" ";
            }else if(value.type == 'between'){
                join += value.colum+" BETWEEN '"+ value.value+"' AND '" + value.valueTwo+ "' "+value.join+" ";
            }else if(value.type == 'not_between'){
                join += " NOT ("+value.colum+" BETWEEN '"+ value.value+"' AND '" + value.valueTwo+"') "+value.join+" ";
            }else if(value.type == 'is_null'){
                join += value.colum+" IS NULL "+value.join+" ";
            }else if(value.type == 'is_not_null'){
                join += value.colum+" IS NOT NULL "+value.join+" ";
            }

        }

    });

    return join;

}

我会使用不同的结构,因为:

  • 无需区分operatorjoin
  • groupsrules应该是同一个概念。 当它应该有嵌套规则时,只需使用嵌套rules属性。
  • 当您使用inbetween类型invalue属性实际上应该是一个数组。 解析器应该注入逗号和其他 SQL 语法。 不要将逗号放在单个字符串中(尽管您没有这样的例子)
  • 避免分别解析not_betweennot_is_null 它们和is_null between东西是一样的,但NOT应用到它。 这可以更动态地完成。

以下是您的示例的建议结构:

{
    "type": "AND",
    "rules": [{
        "id": 100,
        "column": "dd_Tttp",
        "type": "equal",
        "value": true
    }, {
        "type": "AND",
        "rules": [{
            "id": 200,
            "column": "dd_tering",
            "type": "equal",
            "value": true
        }, {
            "id": 201,
            "column": "dd_Size",
            "type": "in",
            "value": ["Standard"] // You should use arrays for type="in"
        }, {
            "id": 202,
            "column": "dd_Lotpth",
            "type": "equal",
            "value": "12"
        }, {
            "type": "AND",
            "rules": [{
                "id": 300,
                "column": "dd_cat",
                "type": "equal",
                "value": "34"
            }, {
                "id": 301,
                "column": "dd_Cot",
                "type": "in",
                "value": ["Coftlassic"]  // You should use arrays for type="in"
            }, {
                "id": 302,
                "column": "dd_dse",
                "type": "equal",
                "value": "2020-01-01"
            }, {
                "id": 303,
                "column": "dd_turflaid",
                "type": "equal",
                "value": true
            }]
        }]
    }, {
        "type": "AND",
        "rules": [{
            "id": 100,
            "column": "dd_get",
            "type": "equal",
            "value": true
        }, {
            "id": 101,
            "column": "dd_ccc",
            "type": "in",
            "value": ["Standard"] //  // You should use arrays for type="in"
        }]
    }]
};

这是一个从中生成 SQL 的片段:

 const op = { equal: " = ", not_equal: " <> ", less: " < ", less_or_equal: " <= ", greater: " > ", greater_or_equal: " >= " }; function toSql(rule) { // recursive case: if (rule.rules) return "(" + rule.rules.map(toSql).join("\\n" + rule.type + " ") + ")"; // Base case (it is an atomic rule): if (op[rule.type]) return rule.column + op[rule.type] + JSON.stringify(rule.value); // Deal with "not": that is just a negation of the opposite let type = rule.type.replace(/^not_/, ""); let sql = rule.column + ( type === "in" ? " IN (" + JSON.stringify(rule.value).slice(1,-1) + ")" : type === "between" ? " BETWEEN " + rule.value.map(item => JSON.stringify(item)).join(" AND ") : type === "is_null" ? " IS NULL" : "<UNKNOWN TYPE:" + type + ">" ); return type === rule.type ? sql : "NOT (" + sql + ")"; } let rule = {"type": "AND","rules": [{"id": 100,"column": "dd_Tttp","type": "equal","value": true}, {"type": "AND","rules": [{"id": 200,"column": "dd_tering","type": "equal","value": true}, {"id": 201,"column": "dd_Size","type": "in","value": ["Standard"]}, {"id": 202,"column": "dd_Lotpth","type": "equal","value": "12"}, {"type": "AND","rules": [{"id": 300,"column": "dd_cat","type": "equal","value": "34"}, {"id": 301,"column": "dd_Cot","type": "in","value": ["Coftlassic"]}, {"id": 302,"column": "dd_dse","type": "equal","value": "2020-01-01"}, {"id": 303,"column": "dd_turflaid","type": "equal","value": true}]}]}, {"type": "AND","rules": [{"id": 100,"column": "dd_get","type": "equal","value": true}, {"id": 101,"column": "dd_ccc","type": "in","value": ["Standard"]}]}]}; console.log(toSql(rule));

禁用规则

在评论中,您添加了一个要禁用某些规则的要求。 在这种情况下,首先通过新属性disabled过滤规则。

这是具有该更改的相同片段,其中最后两个(嵌套)规则被禁用:

 const op = { equal: " = ", not_equal: " <> ", less: " < ", less_or_equal: " <= ", greater: " > ", greater_or_equal: " >= " }; function toSql(rule) { // recursive case: if (rule.rules) { // Filter out recursive return values that are empty (using Boolean): let sql = rule.rules.map(toSql).filter(Boolean).join("\\n" + rule.type + " "); // return that SQL in parentheses, except when it is empty return sql ? "(" + sql + ")" : ""; } // Base case (it is an atomic rule): if (rule.disabled) return ""; // Return empty string when disabled if (op[rule.type]) return rule.column + op[rule.type] + JSON.stringify(rule.value); // Deal with "not": that is just a negation of the opposite let type = rule.type.replace(/^not_/, ""); let sql = rule.column + ( type === "in" ? " IN (" + JSON.stringify(rule.value).slice(1,-1) + ")" : type === "between" ? " BETWEEN " + rule.value.map(item => JSON.stringify(item)).join(" AND ") : type === "is_null" ? " IS NULL" : "<UNKNOWN TYPE:" + type + ">" ); return type === rule.type ? sql : "NOT (" + sql + ")"; } let rule = {"type": "AND","rules": [{"id": 100,"column": "dd_Tttp","type": "equal","value": true}, {"type": "AND","rules": [{"id": 200,"column": "dd_tering","type": "equal","value": true}, {"id": 201,"column": "dd_Size","type": "in","value": ["Standard"]}, {"id": 202,"column": "dd_Lotpth","type": "equal","value": "12"}, {"type": "AND","rules": [{"id": 300,"column": "dd_cat","type": "equal","value": "34"}, {"id": 301,"column": "dd_Cot","type": "in","value": ["Coftlassic"]}, {"id": 302,"column": "dd_dse","type": "equal","value": "2020-01-01"}, {"id": 303,"column": "dd_turflaid","type": "equal","value": true}]}]}, {"type": "AND","rules": [{"id": 100,disabled:true,"column": "dd_get","type": "equal","value": true}, {"id": 101,disabled:true,"column": "dd_ccc","type": "in","value": ["Standard"]}]}]}; console.log(toSql(rule));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM