From a5a2b7b64eb6b022694b9ca8a14b55815d4de5cf Mon Sep 17 00:00:00 2001 From: xueyinfei <1207092115@qq.com> Date: Fri, 17 Oct 2025 22:25:06 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A1=B5=E9=9D=A2sql=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/BloodAnalysisController.java | 13 +- .../entity/vo/BloodAnalysisBySql.java | 15 ++ .../bloodanalysis/parser/SqlParser.java | 132 ++++++++++++++++-- .../parser/utils/ExportParseResultUtil.java | 26 ++++ .../service/BloodAnalysisService.java | 8 +- 5 files changed, 177 insertions(+), 17 deletions(-) create mode 100644 src/main/java/com/guozhi/bloodanalysis/entity/vo/BloodAnalysisBySql.java diff --git a/src/main/java/com/guozhi/bloodanalysis/controller/BloodAnalysisController.java b/src/main/java/com/guozhi/bloodanalysis/controller/BloodAnalysisController.java index c82bd09..ca096a7 100644 --- a/src/main/java/com/guozhi/bloodanalysis/controller/BloodAnalysisController.java +++ b/src/main/java/com/guozhi/bloodanalysis/controller/BloodAnalysisController.java @@ -1,16 +1,17 @@ package com.guozhi.bloodanalysis.controller; -import com.guozhi.bloodanalysis.parser.SqlParser; +import com.guozhi.bloodanalysis.entity.vo.BloodAnalysisBySql; import com.guozhi.bloodanalysis.service.BloodAnalysisService; import com.guozhi.bloodanalysis.utils.ApiResult; import com.guozhi.bloodanalysis.utils.RedisUtils; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; -import java.io.FileNotFoundException; +import java.util.List; +import java.util.Map; @RestController public class BloodAnalysisController { @@ -33,4 +34,10 @@ public class BloodAnalysisController { return ApiResult.success("启动任务成功,请稍后查看"); } } + + @PostMapping("/sql/analysis") + public ApiResult>> analysisBySQL(@RequestBody BloodAnalysisBySql sqlModel) throws Exception { + List> result = bloodAnalysisService.analysisBySQL(sqlModel); + return ApiResult.success(result); + } } diff --git a/src/main/java/com/guozhi/bloodanalysis/entity/vo/BloodAnalysisBySql.java b/src/main/java/com/guozhi/bloodanalysis/entity/vo/BloodAnalysisBySql.java new file mode 100644 index 0000000..e3ba699 --- /dev/null +++ b/src/main/java/com/guozhi/bloodanalysis/entity/vo/BloodAnalysisBySql.java @@ -0,0 +1,15 @@ +package com.guozhi.bloodanalysis.entity.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class BloodAnalysisBySql { + private String sqlType; + private Integer defaultSystem; + private String defaultModel; + private String sql; +} diff --git a/src/main/java/com/guozhi/bloodanalysis/parser/SqlParser.java b/src/main/java/com/guozhi/bloodanalysis/parser/SqlParser.java index 9635613..4e6236f 100644 --- a/src/main/java/com/guozhi/bloodanalysis/parser/SqlParser.java +++ b/src/main/java/com/guozhi/bloodanalysis/parser/SqlParser.java @@ -155,6 +155,103 @@ public class SqlParser { } } + public List> parse(String procSql, String dbType, Integer defaultSystem, String defaultModel) throws Exception { + try { + String sqlText = ""; + List> resultList = new ArrayList<>(); + List targetSqlList = new ArrayList<>(); + String sql = new GenericLogNormalizer().normalizer(procSql,dbType); + sql = optDeclare(sql,null); + sql = optDeclare2(sql); + if(sql.trim().equals("")){ + throw new BusinessException("errorSQLparse"); + } + targetSqlList.add(sql); + this.parserContext.setDefaultDb(defaultSystem); + this.parserContext.setDefaultSchema(defaultModel); + for (String s : targetSqlList) { + sqlText = s; + if ("ORACLE".equals(dbType)) { + if (Objects.equals(dbType, Oracle.toString())) { + if (sqlText != null) { + sqlText = sqlText.toUpperCase(); + } + } + sqlParser = new TGSqlParser(EDbVendor.dbvoracle); + } + if ("MYSQL".equals(dbType)) { + sqlParser = new TGSqlParser(EDbVendor.dbvmysql); + } + if ("SQLSERVER".equals(dbType)) { + sqlParser = new TGSqlParser(EDbVendor.dbvmssql); + } + if ("TERADATA".equals(dbType)) { + sqlParser = new TGSqlParser(EDbVendor.dbvteradata); + } + if ("POSTGRESQL".equals(dbType)) { + sqlParser = new TGSqlParser(EDbVendor.dbvpostgresql); + } + if ("DB2".equals(dbType)) { + sqlParser = new TGSqlParser(EDbVendor.dbvdb2); + } + sqlParser.sqltext = sqlText; + int ret = sqlParser.parse(); + List result = new ArrayList<>(); + if (ret == 0) { + TStatementList statementList = sqlParser.getSqlstatements(); + while (statementList.hasNext()) { + TCustomSqlStatement stmt = statementList.next(); + parserContext.getTableInCurrentStatement().clear(); + switch (stmt.sqlstatementtype) { + case sstselect: + result = parseSelect(stmt); + break; + case sstdelete: + result = parseDelete(stmt); + break; + case sstupdate: + result = parseUpdate(stmt); + break; + case sstinsert: + result = parseInsert(stmt); + break; + case sstcreatetable: + result = parseCreateTable(stmt); + break; + case sstcreateview: + break; + case sstoraclealtertablespace: + // parseAlterTable(stmt); + break; + case sstdroptable: + // parseDropTable(stmt); + break; + case sstmerge: + log.error("sstmerge[" + + stmt.sqlstatementtype + + "][unknow sql type]sqltext:" + ); + default: + log.error("[" + stmt.sqlstatementtype + + "][unknow sql type]sqltext:" + ); + break; + } + } + } else { + log.error(sqlParser.sqltext + sqlParser.getErrormessage()); + } + if (result.size() > 0) { + resultList = exportParseResultUtil.expResult(result); + } + } + return resultList; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + private String optDeclare(String sql,String procName) { String returnSql=sql; if(StringUtils.isNotEmpty(sql)){ @@ -194,21 +291,36 @@ public class SqlParser { } //找出脚本结束的位置 - Pattern lastPattern = Pattern.compile("(END)(\\s)+"+("".equals(procName)?";":procName)); - Matcher lastMatcher = lastPattern.matcher(sql); - if(lastMatcher.find()){ - int lastIndex = lastMatcher.start(); - if(sql.contains("BEGIN")){ - returnSql = sql.substring(sql.indexOf("BEGIN")+5, lastIndex); + if (procName != null && procName.length()>0){ + Pattern lastPattern = Pattern.compile("(END)(\\s)+"+("".equals(procName)?";":procName)); + Matcher lastMatcher = lastPattern.matcher(sql); + if(lastMatcher.find()){ + int lastIndex = lastMatcher.start(); + if(sql.contains("BEGIN")){ + returnSql = sql.substring(sql.indexOf("BEGIN")+5, lastIndex); + }else{ + returnSql = sql.substring(0, lastIndex); + } }else{ - returnSql = sql.substring(0, lastIndex); + Pattern tempPattern = Pattern.compile("(END)(\\s)*;"); + Matcher tempMatcher = tempPattern.matcher(sql); + Pattern tempPatternBegin = Pattern.compile("(\\s)(BEGIN)(\\s)"); + Matcher tempMatcherBegin = tempPatternBegin.matcher(sql); + + if(tempMatcher.find()){ + int tempIndex = tempMatcher.start(); + int tempIndexBegin = 0; + if(tempMatcherBegin.find()){ + tempIndexBegin = tempMatcherBegin.start(); + } + returnSql = sql.substring(tempIndexBegin+6, tempIndex); + } } - }else{ + }else { Pattern tempPattern = Pattern.compile("(END)(\\s)*;"); Matcher tempMatcher = tempPattern.matcher(sql); Pattern tempPatternBegin = Pattern.compile("(\\s)(BEGIN)(\\s)"); Matcher tempMatcherBegin = tempPatternBegin.matcher(sql); - if(tempMatcher.find()){ int tempIndex = tempMatcher.start(); int tempIndexBegin = 0; @@ -218,7 +330,6 @@ public class SqlParser { returnSql = sql.substring(tempIndexBegin+6, tempIndex); } } - } return returnSql; } @@ -250,7 +361,6 @@ public class SqlParser { return returnVal.toString(); } - private List parseAlterTable(TCustomSqlStatement stmt) { TAlterTableStatement alterTableStatement=(TAlterTableStatement)stmt; AlterParser parser=new AlterParser(alterTableStatement,parserContext); diff --git a/src/main/java/com/guozhi/bloodanalysis/parser/utils/ExportParseResultUtil.java b/src/main/java/com/guozhi/bloodanalysis/parser/utils/ExportParseResultUtil.java index ebb3a77..0c7cc00 100644 --- a/src/main/java/com/guozhi/bloodanalysis/parser/utils/ExportParseResultUtil.java +++ b/src/main/java/com/guozhi/bloodanalysis/parser/utils/ExportParseResultUtil.java @@ -31,6 +31,14 @@ public class ExportParseResultUtil { log.info("解析结果导出完成"); } + public List> expResult(List kColumns) throws Exception{ + List result = new ArrayList<>(); + for (KColumn tCol : kColumns) { + getOutList(kColumns, tCol, tCol.getRefColumns(), result); + } + return outTable(result); + } + private void outTable(List result, DataLineageInfo dataLineageInfo){ for (String line : result) { String lines [] = line.split(","); @@ -51,6 +59,24 @@ public class ExportParseResultUtil { metaBloodAnalysisMapper.insert(metaBloodAnalysis); } } + private List> outTable(List result){ + List> list = new ArrayList<>(); + for (String line : result) { + String lines [] = line.split(","); + Map map = new HashMap<>(); + map.put("sourceSysId",lines[0]); + map.put("sourceMdlName",lines[1]); + map.put("sourceTableName",lines[2]); + map.put("sourceColName",lines[3]); + map.put("targetSysId",lines[4]); + map.put("targetMdlName",lines[5]); + String[] arr = lines[6].split("\\."); + String targetTableName = arr[arr.length-1]; + map.put("targetTableName",targetTableName); + map.put("targetColName",lines[7]); + } + return list; + } private void getOutList(List kColumns,KColumn tCol,List sCols,List list){ if(tCol.vColumn){ diff --git a/src/main/java/com/guozhi/bloodanalysis/service/BloodAnalysisService.java b/src/main/java/com/guozhi/bloodanalysis/service/BloodAnalysisService.java index e20c100..8efaf69 100644 --- a/src/main/java/com/guozhi/bloodanalysis/service/BloodAnalysisService.java +++ b/src/main/java/com/guozhi/bloodanalysis/service/BloodAnalysisService.java @@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.github.pagehelper.PageHelper; import com.guozhi.bloodanalysis.entity.DataLineageInfo; +import com.guozhi.bloodanalysis.entity.vo.BloodAnalysisBySql; import com.guozhi.bloodanalysis.mapper.DataLineageInfoMapper; import com.guozhi.bloodanalysis.mapper.MetaBloodAnalysisMapper; import com.guozhi.bloodanalysis.parser.SqlParser; @@ -21,7 +22,6 @@ import org.springframework.context.ApplicationContext; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; -import javax.servlet.http.HttpServletRequest; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -50,8 +50,6 @@ public class BloodAnalysisService { @Autowired RedisUtils redisUtils; -// @Autowired -// HttpServletRequest request; @Async public void analysis(String dashUserName,String dashPassword) { @@ -107,4 +105,8 @@ public class BloodAnalysisService { } } + public List> analysisBySQL(BloodAnalysisBySql sqlModel) throws Exception { + SqlParser sqlParser = applicationContext.getBean(SqlParser.class); + return sqlParser.parse(sqlModel.getSql(), sqlModel.getSqlType(), sqlModel.getDefaultSystem(), sqlModel.getDefaultModel()); + } }