SQL校验⽅法
问题简介:在⼯作中,表字段多到⼀定程度,Select 中的字段和结果集中的字段对⽐很⿇烦,还容易出错。于是写了⼀个检查Select和Insert的⽅法。(使⽤的是Scala语⾔)
  1. 代码如下
import scala.annotation.tailrec
/**
* 校验SQL,现⽀持三种校验
* select 查询校验:select语句与结果集⽐对
* insert into select 查询插⼊校验:查询语句与插⼊语句
* insert into 插⼊校验:insert字段与values中的值数量
*
*/
object TestSQL extends App {
//select语句测试sql
val selectStr =
"""
|select
|name,
|password,
|hello2,
|hello2,
|hello2
| from
|  testTables
|
|rs.getString("name")
|rs.getString("password")
|rs.getString("hello")
|rs.getString("hello")
""".stripMargin
//insert测试语句
val insertStr =
"""
|Insert
|into
|testTable
|(name,
|password,
|hello2,,,)
| values
|(,,,,,)
""".stripMargin
//insert into select测试语句
val insertAndSelectSql =
s"""
|insert
|into
|testTable
|(name,
|password,
|password,
|hello)
| values
|select
|name,
|password,
|hello2,
|hello2,
|hello3
| from
|  testTable2
""".stripMargin
//测试⽅法
sqlTest(insertAndSelectSql)
/**
* 判断字符串中关键字,匹配校验语句
*
* @param str 待判断的字符串
*/
def sqlTest(str: String): Unit = {
//将字符串转换成⼩写
val strLower = LowerCase
judgeSQL(strLower) match {
case (true, false) => selectTest(strLower)
case (false, true) => insertTest(strLower)
case (true, true) => insertAndSelectTest(strLower)
case (_, _) => println("暂不⽀持该SQL")
}
}
/**
* 查询语句和结果集字段校验
*
* @param selectStr 包含select语句和结果集的字符串
*/
private def selectTest(selectStr: String): Unit = {
//1.将select与from中的字段,放⼊链表中
val selectLists: List[String] = strToList(getSubString(selectStr, "select", "from", 6))    //2.获取rs.get中所有的值
var rsLists: List[String] = List()
rsLists = nextElement(selectStr, rsLists)
//3.判断select语句和结果集获取的值中的参数是否重复
judgeIsEquals(selectLists, "select")
judgeIsEquals(rsLists, "result")
//4.判断select中列的数量和结果集是否相等
judgeFieldsNums(selectLists.size, rsLists.size, "select")
//5.⽐较select语句和结果集获取的值中的参数是否相等
judgeFields(selectLists, rsLists, "select")
}
/**
* insert into select 语句校验
*
* @param insertAndSelectStr 查询插⼊语句字符串
*/
private def insertAndSelectTest(insertAndSelectStr: String): Unit = {
//1.将select与from中的字段,并计算数量
//1.1截取select和from中的⼦字符串
val selectSubFront = getSubString(insertAndSelectStr, "select", "from", 6)
//1.2将select和from中的列放⼊链表集合中
val selectLists: List[String] = strToList(selectSubFront)
//1.3.判断select语句中的参数是否重复
judgeIsEquals(selectLists, "select")
//2.截取insert和select中间的字符串,计算字段数量
/
/2.1截取insert和values中的⼦字符串
val insertSubFront = getSubString(insertAndSelectStr, "insert", "values", 0)
//2.2再截取“()”内列的集合
val insertSubFrontList = strToList(getSubString(insertSubFront, "(", ")", 1))
//2.3判断insert语句中字段是否有重复
judgeIsEquals(insertSubFrontList, "insert")
//3.判断insert和select中列的数量是否相等
judgeFieldsNums(selectLists.size, insertSubFrontList.size, "insertAndSelect")
//4.判断insert语句中的字段与select中是否相等
judgeFields(selectLists, insertSubFrontList, "insertAndSelect")
}
/
**
* 插⼊SQL校验
*
* @param insertStr 插⼊语句sql
*/
private def insertTest(insertStr: String): Unit = {
//1.获取insert和values之间的字符串
val insertSubFront = getSubString(insertStr, "insert", "values", 0)
val insertSubFrontNums = countNumbers(insertSubFront)
//2.获取values之后的字符串
val insertSubBack = insertStr.substring(insertStr.indexOf("values"))
val insertSubBackNums = countNumbers(insertSubBack)
//3.判断两个字符串中的','数量差值
judgeFieldsNums(insertSubFrontNums, insertSubBackNums, "insert")
}
/**
* 获取结果集中字段组成的链表集合
*
* @param string 包含select和结果集的字符串
* @param list  空list集合
* @return 返回结果集中字段组成的链表集合
*/
@tailrec
private def nextElement(string: String, list: List[String]): List[String] = {
val rightIndex = string.indexOf("\")")
val leftIndex = string.indexOf("(\"") + 2
val lists = list.::(string.substring(leftIndex, rightIndex))
val subString = string.substring(rightIndex + 2)
if ( string.lastIndexOf("\")").hashCode() == rightIndex.hashCode() ) {
lists
} else {
nextElement(subString, lists)
}
}
/**
* 计算“,”的数量
*
* @param strs 待计算的字符串
* @return “,”的数量
*/
private def countNumbers(strs: String): Integer = {
//计算包含','字符的数量
var count: Integer = 0
strs.foreach {
str =>
if ( str == ',' ) {
count = count + 1
}
}
count
}
/**
* 判断是否是包含SQL关键字
*
* @param str 待校验的字符串
* @return
*/
private def judgeSQL(str: String): (Boolean, Boolean) = {
//是否有insert关键字
val isHasInsert = ains("insert")
//是否有select关键字
val isHasSelect = ains("select")
(isHasSelect, isHasInsert)
}
/**
* 获取⼦字符串
*
* @param parString    ⽗字符串
* @param firstString  sql语句第⼀个关键字
* @param secoundString sql语句第⼆个关键字
* @param shift        下标位移距离
* @return 字符串
*/
private def getSubString(parString: String, firstString: String, secoundString: String, shift: Integer): String = {    parString.substring(parString.indexOf(firstString) + shift, parString.indexOf(secoundString))
}
/**
* 将字符串转换为List集合
*
* @param strToListString 将被转换为集合的字符串
* @return String类型的集合
*/
private def strToList(strToListString: String): List[String] = {
}
/**
* List集合验重
*
* @param list      将被校验的list
* @param typeString 涉及SQL语句类型
*/
private def judgeIsEquals(list: List[String], typeString: String): Unit = {
val tmpListResult: Boolean = list.distinct.size != list.size
case "SELECT" => if ( tmpListResult ) println("查询语句有重复值")
case "INSERT" => if ( tmpListResult ) println("插⼊语句有重复值")
case "RESULT" => if ( tmpListResult ) println("结果集有重复值")
case _ => println("暂不⽀持该SQL语句验重")
}
}
/
**
* ⽐较SQL中字段数量
*
* @param firstNum  第⼀个需要⽐较字段的数量
* @param secoundNum 第⼆个需要⽐较字段的数量
* @param typeString SQL类型
*/
private def judgeFieldsNums(firstNum: Integer, secoundNum: Integer, typeString: String): Unit = {    var delNums = firstNum - secoundNum
val delNumsCompare = firstNumpareTo(secoundNum)
(UpperCase(), delNumsCompare) match {
case ("SELECT", -1) =>
delNums = -delNums
println(s"结果集多了[$delNums]个数据")
case ("SELECT", 1) =>
println(s"SELECT 多了[$delNums]个数据")
case ("SELECT", 0) =>
println(s"SELECT语句与结果集中字段数量相等")
case ("INSERT", -1) =>
delNums = -delNums
println(s"VALUES 多了[$delNums]个数据")
case ("INSERT", 1) =>
println(s"INSERT 多了[$delNums]个数据")
字符串截取 sql
case ("INSERT", 0) =>
println(s"INSERT语句中字段字段数量相等")
case ("INSERTANDSELECT", -1) =>
delNums = -delNums
println(s"INSERT 多了[$delNums]个数据")
case ("INSERTANDSELECT", 1) =>
println(s"SELECT 多了[$delNums]个数据")
case ("INSERTANDSELECT", 0) =>
println(s"INSERT语句和SELCECT语句中字段数量相等")
case _ => println("暂不⽀持该SQL语句⽐较字段数量")
}
}
/**
* 判断字段是否相等
*
* @param firstList  第⼀个待⽐较集合
* @param secoundList 第⼆个待⽐较集合
* @param typeString  SQL类型
*/
private def judgeFields(firstList: List[String], secoundList: List[String], typeString: String): Unit = {    val selectSurplus = Set -- Set
val insertSubFrontSurplus = Set -- Set
case "SELECT" =>
if ( Empty ) {
println("select语句中⽐结果集多的字段有" + selectSurplus)
}
if ( Empty ) {
println("结果集中⽐select语句多的字段有" + insertSubFrontSurplus)
}
if ( selectSurplus.isEmpty && insertSubFrontSurplus.isEmpty ) {
println("select语句中与结果集字段相同")
}
case "INSERTANDSELECT" =>
if ( Empty ) {
println("select语句中⽐insert多的字段有" + selectSurplus)
}
if ( Empty ) {
println("insert语句中⽐select多的字段有" + insertSubFrontSurplus)
}
if ( selectSurplus.isEmpty && insertSubFrontSurplus.isEmpty ) {
println("insert语句中与select语句中的字段相同")
}
}
}
}
  2. ⽀持的校验类型:现⽀持三种校验
(1).select 查询校验:select语句与结果集⽐对
(2).insert into select 查询插⼊校验:查询语句与插⼊语句
(3).insert into 插⼊校验:insert字段与values中的值数量

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。