时间:2021-07-01 10:21:17 帮助过:8人阅读
获得了这些,就而已重组得到原始SQL语句,并且对其进行各种改写。
mysql 中的insert语法如下:
mysql> ? insert
Name: ‘INSERT‘
Description:
Syntax:
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name
[PARTITION (partition_name,...)]
[(col_name,...)]
{VALUES | VALUE} ({expr | DEFAULT},...),(...),...
[ ON DUPLICATE KEY UPDATE
col_name=expr
[, col_name=expr] ... ]
Or:
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name
[PARTITION (partition_name,...)]
SET col_name={expr | DEFAULT}, ...
[ ON DUPLICATE KEY UPDATE
col_name=expr
[, col_name=expr] ... ]
Or:
INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name
[PARTITION (partition_name,...)]
[(col_name,...)]
SELECT ...
[ ON DUPLICATE KEY UPDATE
col_name=expr
[, col_name=expr] ... ]
2. 解析 update 语句:
public static String convertUpdateSQL(String sql){
try{
MySqlStatementParser parser = new MySqlStatementParser(sql);
SQLStatement stmt = parser.parseStatement();
MySqlUpdateStatement update = (MySqlUpdateStatement)stmt;
SQLTableSource ts = update.getTableSource();
if(ts != null && ts.toString().contains(",")){
System.out.println(ts.toString());
LOGGER.warn("Do not support Multiple-table udpate syntax...");
return sql;
}
String tableName = StringUtil.removeBackquote(update.getTableName().getSimpleName());
if(!isGlobalTable(tableName))
return sql;
if(!isInnerColExist(tableName))
return sql; // 没有内部列
StringBuilder sb = new StringBuilder(150);
SQLExpr se = update.getWhere();
// where中有子查询: update company set name=‘com‘ where id in (select id from xxx where ...)
if(se instanceof SQLInSubQueryExpr){
// return sql;
int idx = sql.toUpperCase().indexOf(" SET ") + 5;
sb.append(sql.substring(0, idx)).append(GLOBAL_TABLE_MYCAT_COLUMN)
.append("=").append(operationTimestamp)
.append(",").append(sql.substring(idx));
return sb.toString();
}
String where = null;
if(update.getWhere() != null)
where = update.getWhere().toString();
SQLOrderBy orderBy = update.getOrderBy();
Limit limit = update.getLimit();
sb.append("update ").append(tableName).append(" set ");
List<SQLUpdateSetItem> items = update.getItems();
boolean flag = false;
for(int i=0; i<items.size(); i++){
SQLUpdateSetItem item = items.get(i);
String col = item.getColumn().toString();
String val = item.getValue().toString();
if(StringUtil.removeBackquote(col)
.equalsIgnoreCase(GLOBAL_TABLE_MYCAT_COLUMN)){
flag = true;
sb.append(col).append("=");
if(i != items.size() - 1)
sb.append(operationTimestamp).append(",");
else
sb.append(operationTimestamp);
}else{
sb.append(col).append("=");
if(i != items.size() -1 )
sb.append(val).append(",");
else
sb.append(val);
}
}
if(!flag){
sb.append(",").append(GLOBAL_TABLE_MYCAT_COLUMN)
.append("=").append(operationTimestamp);
}
sb.append(" where ").append(where);
if(orderBy != null && orderBy.getItems()!=null
&& orderBy.getItems().size() > 0){
sb.append(" order by ");
for(int i=0; i<orderBy.getItems().size(); i++){
SQLSelectOrderByItem item = orderBy.getItems().get(i);
SQLOrderingSpecification os = item.getType();
sb.append(item.getExpr().toString());
if(i < orderBy.getItems().size() - 1){
if(os != null)
sb.append(" ").append(os.toString());
sb.append(",");
}else{
if(os != null)
sb.append(" ").append(os.toString());
}
}
}
if(limit != null){ // 分为两种情况: limit 10; limit 10,10;
sb.append(" limit ");
if(limit.getOffset() != null)
sb.append(limit.getOffset().toString()).append(",");
sb.append(limit.getRowCount().toString());
}
return sb.toString();
}catch(Exception e){
LOGGER.warn(e.getMessage());
return sql;
}
}
同样三行,解析update语句:
MySqlStatementParser parser = new MySqlStatementParser(sql);
SQLStatement stmt = parser.parseStatement();
MySqlUpdateStatement update = (MySqlUpdateStatement)stmt;
如果是 多表 udpate 语句,可以使用下面的语句进行判断:
SQLTableSource ts = update.getTableSource();
if(ts != null && ts.toString().contains(",")){
System.out.println(ts.toString());
LOGGER.warn("Do not support Multiple-table udpate syntax...");
return sql;
}
如果是单表update语句:
获得 update 语句的 where 部分:
SQLExpr se = update.getWhere();
// where中有子查询: update company set name=‘com‘ where id in (select id from xxx where ...)
if(se instanceof SQLInSubQueryExpr){
// return sql;
int idx = sql.toUpperCase().indexOf(" SET ") + 5;
sb.append(sql.substring(0, idx)).append(GLOBAL_TABLE_MYCAT_COLUMN)
.append("=").append(operationTimestamp)
.append(",").append(sql.substring(idx));
return sb.toString();
}
String where = null;
if(update.getWhere() != null)
where = update.getWhere().toString();
如果where 部分由 select 语句,由:se instanceof SQLInSubQueryExpr 来判断。
order by 和 limit 部分分别由:
SQLOrderBy orderBy = update.getOrderBy();
Limit limit = update.getLimit();
获得。
update 对应的 列和值,有下面的代码获得:
boolean flag = false;
for(int i=0; i<items.size(); i++){
SQLUpdateSetItem item = items.get(i);
String col = item.getColumn().toString();
String val = item.getValue().toString();
解析得到了这些部分,就可以重组出原始的 update 语句,并且按照自己的需求进行SQL改写。
解析器:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.14</version>
</dependency>
利用 druid 解析器解析SQL
标签: