Commit de93953303db3a8cadcde8f09289a81e6576d7b8
1 parent
07ecddbb
Exists in
master
and in
2 other branches
fix a bug about core sql split
Showing
1 changed file
with
69 additions
and
44 deletions
Show diff stats
src/main/java/com/taover/repository/UtilsSql.java
| @@ -2,6 +2,7 @@ package com.taover.repository; | @@ -2,6 +2,7 @@ package com.taover.repository; | ||
| 2 | 2 | ||
| 3 | import java.util.HashMap; | 3 | import java.util.HashMap; |
| 4 | import java.util.Map; | 4 | import java.util.Map; |
| 5 | +import java.util.Stack; | ||
| 5 | 6 | ||
| 6 | import org.springframework.util.StringUtils; | 7 | import org.springframework.util.StringUtils; |
| 7 | 8 | ||
| @@ -9,62 +10,80 @@ public class UtilsSql { | @@ -9,62 +10,80 @@ public class UtilsSql { | ||
| 9 | 10 | ||
| 10 | public static String[] splitCoreSql(String coreSql) throws Exception { | 11 | public static String[] splitCoreSql(String coreSql) throws Exception { |
| 11 | //去除''内的信息 | 12 | //去除''内的信息 |
| 12 | - String coreSqlRemoveQuate = replaceSelectAndFromBetweenTopCornerMark(coreSql.toUpperCase()); | ||
| 13 | - int fromIndex = calcFromIndex(coreSqlRemoveQuate); | 13 | + int fromIndex = calcFromIndex(coreSql); |
| 14 | if(fromIndex > -1) { | 14 | if(fromIndex > -1) { |
| 15 | return new String[] {coreSql.substring(0, fromIndex), coreSql.substring(fromIndex, coreSql.length())}; | 15 | return new String[] {coreSql.substring(0, fromIndex), coreSql.substring(fromIndex, coreSql.length())}; |
| 16 | }else { | 16 | }else { |
| 17 | throw new Exception("未找到FROM子句"); | 17 | throw new Exception("未找到FROM子句"); |
| 18 | } | 18 | } |
| 19 | } | 19 | } |
| 20 | - | ||
| 21 | - private static int calcFromIndex(String coreSqlUpper) { | ||
| 22 | - //计算位置 | ||
| 23 | - int selectSubSqlNum = 0; | ||
| 24 | - int currWindowIndex = 0; | ||
| 25 | - for(currWindowIndex=0; (currWindowIndex+6)<coreSqlUpper.length(); ) { | ||
| 26 | - String currSubStr = coreSqlUpper.substring(currWindowIndex, currWindowIndex+6); | ||
| 27 | - if("SELECT".equals(currSubStr)) { | ||
| 28 | - ++selectSubSqlNum; | ||
| 29 | - currWindowIndex += 6; | ||
| 30 | - }else if(currSubStr.startsWith(" FROM")) { | ||
| 31 | - if(selectSubSqlNum == 1) { | ||
| 32 | - return currWindowIndex; | ||
| 33 | - } | ||
| 34 | - --selectSubSqlNum; | ||
| 35 | - currWindowIndex += 5; | 20 | + |
| 21 | + private static int calcFromIndex(String coreSql) { | ||
| 22 | + Stack<String> operStack = new Stack<String>(); | ||
| 23 | + String coreSqlUpperCase = coreSql.toUpperCase(); | ||
| 24 | + int sqlLen = coreSqlUpperCase.length(); | ||
| 25 | + int currIndex = 0; | ||
| 26 | + while(currIndex < sqlLen) { | ||
| 27 | + String originContainBlank = subFirstStrEndWithBlank(coreSqlUpperCase, currIndex); | ||
| 28 | + String itemWithoutBlank = originContainBlank.trim(); | ||
| 29 | + if("".equals(itemWithoutBlank)) { | ||
| 30 | + currIndex += originContainBlank.length(); | ||
| 31 | + continue; | ||
| 36 | } | 32 | } |
| 37 | - ++currWindowIndex; | 33 | + if(operStack.isEmpty() && "FROM".equals(itemWithoutBlank)) { |
| 34 | + return currIndex; | ||
| 35 | + } | ||
| 36 | + dealCoupleMark(itemWithoutBlank, operStack); | ||
| 37 | + currIndex += originContainBlank.length(); | ||
| 38 | } | 38 | } |
| 39 | return -1; | 39 | return -1; |
| 40 | } | 40 | } |
| 41 | - | ||
| 42 | - private static String replaceSelectAndFromBetweenTopCornerMark(String sql) { | ||
| 43 | - StringBuffer result = new StringBuffer(); | ||
| 44 | - boolean isBetweenMark = false; | ||
| 45 | - int iMark = 0; | ||
| 46 | - int currIndex = 0; | ||
| 47 | - for(currIndex=0; currIndex<sql.length(); ++currIndex) { | ||
| 48 | - char currChar = sql.charAt(currIndex); | ||
| 49 | - if(currChar == '\'') { | ||
| 50 | - if(!isBetweenMark) { | ||
| 51 | - result.append(sql.substring(iMark, currIndex)); | ||
| 52 | - isBetweenMark = true; | ||
| 53 | - }else { | ||
| 54 | - result.append(sql.substring(iMark, currIndex).replaceAll("SELECT", "******").replaceAll("FROM", "****")); | ||
| 55 | - isBetweenMark = false; | 41 | + private static void dealCoupleMark(String itemWithoutBlank, Stack<String> operStack) { |
| 42 | + char preChar = ' '; | ||
| 43 | + for(int i=0; i<itemWithoutBlank.length(); ++i) { | ||
| 44 | + char currChar = itemWithoutBlank.charAt(i); | ||
| 45 | + if(preChar != '\\' && currChar == '\'') { | ||
| 46 | + if(operStack.isEmpty() || !operStack.peek().equals("'")) { | ||
| 47 | + operStack.push("'"); | ||
| 48 | + }else if(operStack.peek().equals("'")) { | ||
| 49 | + operStack.pop(); | ||
| 50 | + } | ||
| 51 | + }else if(currChar == '('){ | ||
| 52 | + if(operStack.isEmpty() || !operStack.peek().equals("'")) { | ||
| 53 | + operStack.push("("); | ||
| 54 | + } | ||
| 55 | + }else if(currChar == ')') { | ||
| 56 | + if(!operStack.isEmpty() && operStack.peek().equals("(")) { | ||
| 57 | + operStack.pop(); | ||
| 56 | } | 58 | } |
| 57 | - iMark = currIndex; | ||
| 58 | - }else if(currChar == '\\') { | ||
| 59 | - ++currIndex; | ||
| 60 | } | 59 | } |
| 60 | + preChar = currChar; | ||
| 61 | } | 61 | } |
| 62 | - if(iMark > -1) { | ||
| 63 | - result.append(sql.substring(iMark, currIndex)); | ||
| 64 | - } | ||
| 65 | - return result.toString(); | ||
| 66 | } | 62 | } |
| 67 | - | 63 | + |
| 64 | + private static String subFirstStrEndWithBlank(String coreSqlUpperCase, int startIndex) { | ||
| 65 | + boolean startWithBlank = coreSqlUpperCase.charAt(startIndex)==' '; | ||
| 66 | + int endIndex = startIndex; | ||
| 67 | + int sqlLen = coreSqlUpperCase.length(); | ||
| 68 | + char preChar = '0'; | ||
| 69 | + for(int i=startIndex; i<sqlLen; ++i) { | ||
| 70 | + char currChar = coreSqlUpperCase.charAt(i); | ||
| 71 | + if(startWithBlank && currChar!=' ') { | ||
| 72 | + endIndex = i; | ||
| 73 | + break; | ||
| 74 | + } | ||
| 75 | + if(!startWithBlank && currChar!=' ' && preChar==' ') { | ||
| 76 | + endIndex = i; | ||
| 77 | + break; | ||
| 78 | + } | ||
| 79 | + preChar = currChar; | ||
| 80 | + if(i == sqlLen-1) { | ||
| 81 | + endIndex = sqlLen; | ||
| 82 | + } | ||
| 83 | + } | ||
| 84 | + return coreSqlUpperCase.substring(startIndex, endIndex); | ||
| 85 | + } | ||
| 86 | + | ||
| 68 | /** | 87 | /** |
| 69 | * 获取排序字符串 | 88 | * 获取排序字符串 |
| 70 | * @param sort | 89 | * @param sort |
| @@ -145,7 +164,8 @@ public class UtilsSql { | @@ -145,7 +164,8 @@ public class UtilsSql { | ||
| 145 | 164 | ||
| 146 | public static void main(String[] args) { | 165 | public static void main(String[] args) { |
| 147 | String[] testSql = new String[] { | 166 | String[] testSql = new String[] { |
| 148 | - "select actionFrom t,(select * as 'fromCActio', dd as 'seelctsele\'ctd' from t) from www where 223", | 167 | + "\\", |
| 168 | + "select actionFrom as 'seelctsele\\'ctd',(select a as 'fromCActio' from t) from www where 223=1 ", | ||
| 149 | "SELECT wxorder_order.refund_way refundWay,wxorder_order.refund_delivery_sn refundDeliverySn, (SELECT sum(wxorder_compensate.`ware_refund_money`) from `wxorder_compensate` where wxorder_compensate.`order_id` = wxorder_order.id) as wareRefundMoney,(SELECT sum(wxorder_compensate.`refund_money`) from `wxorder_compensate` where wxorder_compensate.`order_id` = wxorder_order.id) as refundMoney, wxorder_order.operate_refund_time applyCompensateTime,wxorder_order.refund_instructions refundInstructions, wxorder_order.channel_id channelId, wxorder_channel.name channelName, wxorder_channel.platform_code platformCode, wxorder_order.pre_control_status as refundPreStatus, wxorder_order.ware_id wareId, wxorder_ware.name wareName, wxorder_order.id, wxorder_order.order_sn orderSn, wxorder_order.upload_sn uploadSn, wxorder_order.money_paid moneyPaid, wxorder_order.consignee, wxorder_order.mobile, wxorder_order.province_name provinceName, wxorder_order.city_name cityName, wxorder_order.district_name districtName, wxorder_order.address, wxorder_order.channel_remark channelRemark, wxorder_order.customer_remark customerRemark, wxorder_order.platform_customer_remark platformCustomerRemark, wxorder_order.sender_name senderName, wxorder_order.sender_mobile senderMobile, date_format(wxorder_order.create_time, '%Y-%m-%d %H:%i:%s') createTime, date_format(wxorder_order.real_delivery_time, '%Y-%m-%d %H:%i:%s') realDeliveryTime, wxorder_order.progress_distribute progressDistribute, wxorder_order.progress_delivery progressDelivery, wxorder_order.control_status controlStatus, wxorder_order.express_name expressName, wxorder_order.express_number expressNumber,wxorder_order.shipping_price shippingPrice, wxorder_order.customer_network_name ,(select count(*) from wxorder_compensate WHERE wxorder_compensate.order_id = wxorder_order.id) as compensateCountAll,(select count(*) from wxorder_compensate WHERE wxorder_compensate.order_id = wxorder_order.id and wxorder_compensate.progress_status = 1) as compensateCountDealed ,(select count(*) from wxorder_channel_refund_payment where wxorder_channel_refund_payment.order_id = wxorder_order.id) as channelRefundPaymentStatus,(select count(*) from wxorder_ware_refund_payment where wxorder_ware_refund_payment.order_id = wxorder_order.id) as wareRefundPaymentStatus FROM wxorder_order wxorder_order INNER JOIN wxorder_channel wxorder_channel ON wxorder_order.channel_id=wxorder_channel.id and wxorder_channel.tenant_id=54 INNER JOIN wxorder_ware wxorder_ware ON wxorder_order.ware_id=wxorder_ware.id and wxorder_ware.tenant_id=54 INNER JOIN wxorder_order_goods wxorder_order_goods ON wxorder_order.id=wxorder_order_goods.order_id and wxorder_order_goods.tenant_id=54 WHERE 1=1 AND wxorder_order.tenant_id='54' AND wxorder_order.control_status='4' GROUP BY wxorder_order.id", | 169 | "SELECT wxorder_order.refund_way refundWay,wxorder_order.refund_delivery_sn refundDeliverySn, (SELECT sum(wxorder_compensate.`ware_refund_money`) from `wxorder_compensate` where wxorder_compensate.`order_id` = wxorder_order.id) as wareRefundMoney,(SELECT sum(wxorder_compensate.`refund_money`) from `wxorder_compensate` where wxorder_compensate.`order_id` = wxorder_order.id) as refundMoney, wxorder_order.operate_refund_time applyCompensateTime,wxorder_order.refund_instructions refundInstructions, wxorder_order.channel_id channelId, wxorder_channel.name channelName, wxorder_channel.platform_code platformCode, wxorder_order.pre_control_status as refundPreStatus, wxorder_order.ware_id wareId, wxorder_ware.name wareName, wxorder_order.id, wxorder_order.order_sn orderSn, wxorder_order.upload_sn uploadSn, wxorder_order.money_paid moneyPaid, wxorder_order.consignee, wxorder_order.mobile, wxorder_order.province_name provinceName, wxorder_order.city_name cityName, wxorder_order.district_name districtName, wxorder_order.address, wxorder_order.channel_remark channelRemark, wxorder_order.customer_remark customerRemark, wxorder_order.platform_customer_remark platformCustomerRemark, wxorder_order.sender_name senderName, wxorder_order.sender_mobile senderMobile, date_format(wxorder_order.create_time, '%Y-%m-%d %H:%i:%s') createTime, date_format(wxorder_order.real_delivery_time, '%Y-%m-%d %H:%i:%s') realDeliveryTime, wxorder_order.progress_distribute progressDistribute, wxorder_order.progress_delivery progressDelivery, wxorder_order.control_status controlStatus, wxorder_order.express_name expressName, wxorder_order.express_number expressNumber,wxorder_order.shipping_price shippingPrice, wxorder_order.customer_network_name ,(select count(*) from wxorder_compensate WHERE wxorder_compensate.order_id = wxorder_order.id) as compensateCountAll,(select count(*) from wxorder_compensate WHERE wxorder_compensate.order_id = wxorder_order.id and wxorder_compensate.progress_status = 1) as compensateCountDealed ,(select count(*) from wxorder_channel_refund_payment where wxorder_channel_refund_payment.order_id = wxorder_order.id) as channelRefundPaymentStatus,(select count(*) from wxorder_ware_refund_payment where wxorder_ware_refund_payment.order_id = wxorder_order.id) as wareRefundPaymentStatus FROM wxorder_order wxorder_order INNER JOIN wxorder_channel wxorder_channel ON wxorder_order.channel_id=wxorder_channel.id and wxorder_channel.tenant_id=54 INNER JOIN wxorder_ware wxorder_ware ON wxorder_order.ware_id=wxorder_ware.id and wxorder_ware.tenant_id=54 INNER JOIN wxorder_order_goods wxorder_order_goods ON wxorder_order.id=wxorder_order_goods.order_id and wxorder_order_goods.tenant_id=54 WHERE 1=1 AND wxorder_order.tenant_id='54' AND wxorder_order.control_status='4' GROUP BY wxorder_order.id", |
| 150 | "select wdd, fromType from www where 223", | 170 | "select wdd, fromType from www where 223", |
| 151 | }; | 171 | }; |
| @@ -156,9 +176,14 @@ public class UtilsSql { | @@ -156,9 +176,14 @@ public class UtilsSql { | ||
| 156 | String[] data = splitCoreSql(item); | 176 | String[] data = splitCoreSql(item); |
| 157 | System.out.println(data[0]); | 177 | System.out.println(data[0]); |
| 158 | System.out.println(data[1]); | 178 | System.out.println(data[1]); |
| 159 | - } | 179 | + } |
| 160 | } catch (Exception e) { | 180 | } catch (Exception e) { |
| 161 | e.printStackTrace(); | 181 | e.printStackTrace(); |
| 162 | } | 182 | } |
| 183 | + | ||
| 184 | +// String testSub = " asdf asdf asdfaf"; | ||
| 185 | +// System.out.println(subFirstStrEndWithBlank(testSub, 5)); | ||
| 186 | +// System.out.println(subFirstStrEndWithBlank(testSub, 6)); | ||
| 187 | +// System.out.println(subFirstStrEndWithBlank(testSub, 13)); | ||
| 163 | } | 188 | } |
| 164 | } | 189 | } |