[英]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;
}
我会使用不同的结构,因为:
operator
和join
。groups
和rules
应该是同一个概念。 当它应该有嵌套规则时,只需使用嵌套rules
属性。in
或between
类型in
, value
属性实际上应该是一个数组。 解析器应该注入逗号和其他 SQL 语法。 不要将逗号放在单个字符串中(尽管您没有这样的例子)not_between
和not_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.