Commit de93953303db3a8cadcde8f09289a81e6576d7b8

Authored by 王彬
1 parent 07ecddbb

fix a bug about core sql split

src/main/java/com/taover/repository/UtilsSql.java
... ... @@ -2,6 +2,7 @@ package com.taover.repository;
2 2  
3 3 import java.util.HashMap;
4 4 import java.util.Map;
  5 +import java.util.Stack;
5 6  
6 7 import org.springframework.util.StringUtils;
7 8  
... ... @@ -9,62 +10,80 @@ public class UtilsSql {
9 10  
10 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 14 if(fromIndex > -1) {
15 15 return new String[] {coreSql.substring(0, fromIndex), coreSql.substring(fromIndex, coreSql.length())};
16 16 }else {
17 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 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 89 * @param sort
... ... @@ -145,7 +164,8 @@ public class UtilsSql {
145 164  
146 165 public static void main(String[] args) {
147 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 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 170 "select wdd, fromType from www where 223",
151 171 };
... ... @@ -156,9 +176,14 @@ public class UtilsSql {
156 176 String[] data = splitCoreSql(item);
157 177 System.out.println(data[0]);
158 178 System.out.println(data[1]);
159   - }
  179 + }
160 180 } catch (Exception e) {
161 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 }
... ...