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 | 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 | } | ... | ... |