【开发日志(塌陷地)】报错:SQL Error: 207, SQLState: S0001, 列名 'ycmk' 无效
发现问题
当用户名为数字时,用户可正常显示在“用户管理”页面,但当用户名为“ycmk“时,管理员虽可在”用户管理“页面看到其相应信息,但以”ycmk“登录系统时会报错:SQL Error: 207, SQLState: S0001, 列名 ‘ycmk’ 无效,org.hibernate.exception.SQLGrammarException: could not execute query。
解决过程
①首先数据库说无法从String(varchar)转为int,检查了数据库设计和实体类,没有问题。
②换个思路,报错为“列名‘ycmk’无效”,一开始想法是,列名明明是“LiginName”,会不会是做登录功能的把应传静态“LoginName”的地方传成了该列的某一行元素,于是从登录功能开始入手。
LoginController中有这样一句:Tuser user = userService.checkLogin(userName, EncoderHandler.doubleEncode(password) );
去userServiceImpl中找checkLogin:
public Tuser checkLogin(String userName, String password) {
return userDAO.checkLogin(userName, password);
}
再去UserDAOImpl中找checkLogin:
public Tuser checkLogin(String userName, String password) {
Tuser user = new Tuser();
String queryString = "select model from Tuser model where model.loginName=" + userName
+ " and model.password ='" + password + "'";
System.out.println("执行的sql语句" + queryString);
Query query = null;
query = this.getMySession().createQuery(queryString);
// Integer rows = Integer.parseInt(query.uniqueResult().toString());
if (query.list().size() > 0) {
user = (Tuser) query.list().get(0);
}
return user;
}
看到查询语句,开始思考一个问题:什么情况下数据库会把某列的一个元素当成列名,从而报错“列名 ‘ycmk’ 无效”呢?下面在数据库中新建查询,执行以下sql语句:
select * from TUser where LoginName=ycmk and Password='b434a1433be5a8b6abba267c9393043db10fdab0'
查询结果:
列名 ‘ycmk’ 无效。
再执行以下sql语句:
select * from TUser where LoginName='ycmk' and Password='b434a1433be5a8b6abba267c9393043db10fdab0'
查询结果:
31 ycmk b434a1433be5a8b6abba267c9393043db10fdab0 31
显然…是代码里的查询语句少了单引号…改为:
String queryString = "select model from Tuser model where model.loginName='" + userName
+ "' and model.password ='" + password + "'";
小结
从sql语句看很容易,但是从报错“列名‘ycmk’无效”这个结果往前找原因,还是不大容易的,因为自己知道没加单引号的sql语句是错误的,却不清楚数据库会报什么样的错,解决这个问题的过程中还是走了些弯路的,甚至查到了可能是某个版本的SQL Server的bug,编写登录功能的师兄已经毕业了,如果是自己写的代码可能遇到问题更容易想到当初怎么拼的语句吧,或者在学sql语句时不单单学什么是正确的语句,也掌握错误的语句会报什么样的错,都会比现在改bug改的更顺手些吧,还需努力啊。
上一篇: shell之条件判断类型
下一篇: MySQL分页(limit)