sql查询中字符串拼接的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sql查询中字符串拼接的问题相关的知识,希望对你有一定的参考价值。

参考技术A 使用场景:

在使用spring data jpa中的query进行将多个不同类型的id拼接成一个新的id进行查询时,遇到这个问题,主要原因是这些id的数据类型不统一,有varchar又有int类型,而sql在进行字符串拼接时如果一边是int类型,会将varchar类型转换成int类型结合 + ,类似做加法计算了(个人理解,大概是这么个意思),同样的情况在其他类型的运算中也会遇到吧,大概意思就是不同类型的值进行字符串拼接时,有一些会进行自动类型转换,而有一些在这个过程中会出现问题。因此我们需要手动地进行类型转换,而sql语法中提供了对应地函数,见下文:

将字符串与整数拼接,即varchar拼接int,不同类型间进行字符串拼接时会提示将varchar值xxx转换成数据类型int时失败。

由此可见,在做字符串拼接运算时,系统会将字符串varchar类型转化为int,若不能转换则提示错误,转换成功则进行数字计算。

因此需要将类型做一个转换,即都转换为varchar类型

sql中类型转换常用函数:

1.CAST()函数可以将某种数据类型的表达式转化为另一种数据类型

2.CONVERT()函数也可以将制定的数据类型转换为另一种数据类型

举例说明:

Sql动态查询拼接字符串的优化

Sql动态查询拼接字符串的优化

 

最原始的 直接写:string sql="select * from TestTables where 1=1";
... 这样的代码效率很低的,这样影响了数据库的索引引用
如下所示:
private void TestOneMethod()
        { 
            string querySql = "select * from TestTables where 1=1";
            if (hasOneCondition)
            {
                querySql += "oneCondition=‘oneCondition‘";
            }
            if (hasTwoCondition)
            {
                querySql += "twoCondition=‘twoCondition‘";
            }
            if (hasThreeCondition)
            {
                querySql +=  "threeCondition=‘threeCondition‘";
            }
            // ....其他条件
            // ExcSql(querySql)
        }

优化方案A:
去掉 string sql="where 1=1"
那么,在用的时候定义一个变量,用来标志是否应存在了hasWhere=false ,如果已经存在了则 hasWhere=!hasWhere.这样下一次在用的时候就

可以用下面的形式表示了:
private void TestOneMethod()
        { 
            string querySql = "select * from TestTables";
            bool _hasWhere = false;
            if (hasOneCondition)
            {
                querySql += _hasWhere ? "where" : "and" + "oneCondition=‘oneCondition‘";
                _hasWhere = true;
            }
            if (hasTwoCondition)
            {
                querySql += _hasWhere ? "where" : "and" + "twoCondition=‘twoCondition‘";
                _hasWhere = true;
            }
            if (hasThreeCondition)
            {
                querySql += _hasWhere ? "where" : "and" + "threeCondition=‘threeCondition‘";
                _hasWhere = true;
            }
            // ....其他条件
            // ExcSql(querySql)
        }
....

经过优化后,sql的效率提高了,但是仍然存在问题,问题在哪里呢?如果我们每次都这样写的话是不是非常的费力,那么就提出一个通用的方

法,这个通用的方法首先得有一个bool类型的返回值,用来确认当前是否需要hasString。如下,在应用的时候:


private bool SeachHelper(string whereString, bool hasWhere)
        {
            if (!hasWhere)
                whereString = "where" + whereString;
            else
                whereString = "and" + whereString;
            return true;
        }

private void TestTwoMethod()
        {
            string querySql = "select * from TestTables";
            bool _hasWhere = false;
            if (hasOneCondition)
            {
                _hasWhere = SeachHelper(querySql, _hasWhere);
                querySql += "oneCondition=‘oneCondition‘";
            }
            if (hasThreeCondition)
            {
                _hasWhere = SeachHelper(querySql, _hasWhere);
                querySql += "twoCondition=‘twoCondition‘";
            }
            if (hasThreeCondition)
            {
                _hasWhere = SeachHelper(querySql, _hasWhere);
                querySql += "threeCondition=‘threeCondition‘";
            }
            // ....其他条件
            // ExcSql(querySql);
        }

代码简洁了不少,但是仍然粗只能问题,那么问题又是什么呢?
额,字符串来回的拼接非常的浪费资源,那么 ,用StringBuilder啊,好接下来继续。

 private void TestThreeMethod()
        {
            StringBuilder querySql = new StringBuilder();
            querySql.Append("select * from TestTables");
            bool _hasWhere = false;
            if (hasOneCondition)
            {
                _hasWhere = SeachHelper(querySql, _hasWhere);
                querySql.Append("oneCondition=‘oneCondition‘");
            }
            if (hasThreeCondition)
            {
                _hasWhere = SeachHelper(querySql, _hasWhere);
                querySql.Append("twoCondition=‘twoCondition‘");
            }
            if (hasThreeCondition)
            {
                _hasWhere = SeachHelper(querySql, _hasWhere);
                querySql.Append("threeCondition=‘threeCondition‘");
            }
            // ....其他条件
            // ExcSql(querySql.ToString());
        }

等一下,那个公用的方法也得改,当然要改!
 
        private bool SeachHelper(StringBuilder whereString, bool hasWhere)
        {
            if (!hasWhere)
                whereString.Append("where");
            else
                whereString.Append("and");
            return true;
        }

上面就是执行动态查询时的逐步优化,说道优化,其实是有一定的前提的,除了第一种情况最低能,其余的要根据实际的情况来进行确定。
如果查询条件非常少,甚至只有两种的情况的时候,则无所谓了,但是如果查询条件越多,那么后面的方法的效率越高。同时对于代码的可读

性越强,想一下,一个项目通常有多少人在写sql查询,如果没给人的风格不同,那么以后的维护人员就要遭罪了,通过使用通用的方法,那么

以后给代码的维护人员带来方便,同时拼接字符串的带来的额外开销也是不容忽视的,好的代码习惯很重要,一个系统从小的地方去注意,那

么最后一定是一个优秀的系统。












































































































以上是关于sql查询中字符串拼接的问题的主要内容,如果未能解决你的问题,请参考以下文章

sql语句的拼接问题,前端传递过来的字符串我们怎么拼接?

动态执行SQL语句,拼接字符串,select中带有一个变量

sql查询语句怎么拼接字符串

sql拼接两个字段的值空格在哪

java中如何解决sql字符串的拼接

mysql-sql数据拼接