您的位置:首页 > 编程语言 > Java开发

java操作mysql时执行带有日期语句的误区

2016-12-07 23:50 621 查看
最近在写服务器端的一些接口,在用java对mysql进行含有日期信息的查询的时候,遇到了一些问题,分享一下 。

首先把数据库中的一个用于用户签到的表的代码部分贴出来:create table signUpInfo
(
phoneNum nvarchar(11) not null, #手机号码
signTime timestamp not null, #时间戳
foreign key(phoneNum) references usersInformation(phoneNum) #外键,对于我这里主表就不贴了,大家测试可以删去这一句
);      这句sql语句使用与创建用户签到的一张表,其中时间戳是用来记录当前的时间的,也就是当用户请求签到的时候,就把系统的当前时间和手机号插入到表中,作为用户的一项签到记录。
下面插入一条语句,带表用户签到:

insert into signUpInfo values('18351088222',CURRENT_TIMESTAMP);
这样我们的签到表中就会多了一条记录,我是在晚上11点多做的,那么查询下:select * from signUpInfo;结果如下图:



这个时候,我们就有了一条记录,那么就可以用来做测试了。

package com.huan.jsonservlet;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
* Created by liuhu on 2016/11/28.
*/

public class SignDBService {
private Connection conn=DBHelper.getConnection(); #链接数据库

/*
此函数用于更新数据库中签到表中的数据,向里面插入phoneNum用户的签到信息,返回值为0表示服务器异常,
返回值为1签到成功,返回值为2表示不在签到时间,返回值为3表示已经签到,不可重复签到。
*/
public int updateSignUp(String tableName,String phoneNum)
{
int result;
try{
Statement stmt = conn.createStatement();
Date currentTime=new Date(); //当前时间
SimpleDateFormat formatter=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String nowtime=formatter.format(currentTime); //当前时间的字符串表示
String dateTime=nowtime.substring(0,10); //当前时间的日期的字符串表示

//初始化签到的规定时间
String startTime1=dateTime+" 07:30:00";
String endTime1=dateTime+" 08:30:00";
String startTime2=dateTime+" 13:30:00";
String endTime2=dateTime+" 23:55:00"; #此时间是为了写博客特地改的

System.out.println(dateTime);

//创建三个日历对象,用于包装签到时间
Calendar now=Calendar.getInstance();
Calendar start=Calendar.getInstance();
Calendar end=Calendar.getInstance();

int flag=0; //用于标记当前签到时间是否符合要求,不是0就是符合要求
try {
now.setTime(formatter.parse(nowtime));
start.setTime(formatter.parse(startTime1));
end.setTime(formatter.parse(endTime1));
} catch (ParseException e) {
result=0; //表示服务器异常
e.printStackTrace();
}
//对上午的时间段进行比较
if(now.compareTo(start)>=0&&now.compareTo(end)<=0)
{
flag=1;
}
else //对下午的时间段进行比较
{
try {
start.setTime(formatter.parse(startTime2));
end.setTime(formatter.parse(endTime2));
} catch (ParseException e) {
e.printStackTrace();
}
if(now.compareTo(start)>=0&&now.compareTo(end)<=0)
{
flag=2;
}
}
//当flag为false时,表示不在签到时间里
if(flag==0) {
return 2;
}
ResultSet rs=null;

if (flag == 1) {
rs = stmt.executeQuery("select * from " + tableName + " where phoneNum=" + phoneNum
+ " and signTime >= " + startTime1 + " and signTime <= " + endTime2 + ";");
} else if (flag == 2) {
rs = stmt.executeQuery("select * from " + tableName + " where phoneNum=" + phoneNum
+ " and signTime >= " + startTime2 + " and signTime <= " + endTime2 + ";");
}

if(rs==null){ //此时表示可以签到
try {
stmt.executeQuery("insert into " + tableName + " values(" + phoneNum
+ ",CURRENT_TIMESTAMP);");
return 1; //签到成功
}
catch(SQLException e){
result=0; //表示服务器异常
e.printStackTrace();
}
}
else{
return 3; //此时表示已经签到过了,不可重复签到
}
// ResultSet rs=stmt.executeQuery("insert into "+tableName+" values("+phoneNum
// +",CURRENT_TIMESTAMP);");
}catch(SQLException e){
result=0; //表示服务器异常
e.printStackTrace();
}
return result;
}
public static void main(String[] args){
SignDBService service=new SignDBService();
int result=service.updateSignUp("signUpInfo","18351088222");
System.out.println(result);

}
}
对于链接数据库部分的代码我也就省略了,不在这里介绍,执行上面的代码,会出现如下的错误:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '13:30:00 and signTime <= 2016-12-07 23:55:00' at line 1

0
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
at com.mysql.jdbc.Util.getInstance(Util.java:408)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:943)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3970)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3906)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2524)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2677)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2545)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2503)
at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1369)
at com.huan.jsonservlet.SignDBService.updateSignUp(SignDBService.java:131)
at com.huan.jsonservlet.SignDBService.main(SignDBService.java:159)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

       看到这么多报错,说实话还是挺蒙的,看第一句中 ,提示的是sql语法错误,并提示了 near '13:30:00 and signTime <= 2016-12-07 23:55:00,那就很容易定位错误了,迅速找到这行代码,如下:

if (flag == 1) {
rs = stmt.executeQuery("select * from " + tableName + " where phoneNum=" + phoneNum
+ " and signTime >= " + startTime1 + " and signTime <= " + endTime2 + ";");
} else if (flag == 2) {
rs = stmt.executeQuery("select * from " + tableName + " where phoneNum=" + phoneNum
+ " and signTime >= " + startTime2 + " and signTime <= " + endTime2 + ";");
}      刚开始看的时候,仔细检查了空格之类的语法,都没有发现什么错误的地方,又将这个语句粘贴到mysql中进行整理测试,也是通过的,在折腾了好久之后,还是没有找到错误,这时候再次去查看错误的时候,猛的一想会不会是因为日期的引号问题啊,当时只是脑子里略过这个想法,然后就抱着试一试的态度,改成了如下:

if (flag == 1) {
rs = stmt.executeQuery("select * from " + tableName + " where phoneNum=" + phoneNum
+ " and signTime >= '" + startTime1 + "' and signTime <= '" + endTime2 + "';");
} else if (flag == 2) {
rs = stmt.executeQuery("select * from " + tableName + " where phoneNum=" + phoneNum
+ " and signTime >= '" + startTime2 + "' and signTime <= '" + endTime2 + "';");
}        乍一看是不是感觉没什么不同,不,请仔细看,我在signTime的地方都加了单引号,然后再次执行程序,便可以正常运行了,这里面就是sql中关于带有数字的查询时的一个问题,记得上数据库课的时候听老师说过,不过当时是查询学好的时候,由于直接输入了数字组成的学号而报错了,当时老师解释是sql server中不能直接这样写,要加上中括号,这次在mysql中遇到了这个类似的错误,这个当然我们在mysql的窗口中是肯定会想起来的了,这个错误在数据库中直接进行查询的时候是很容易被发现和解决的,但是当我们将这个查询语句移植到java中的时候,就多了引号的这一个坎了,一不注意就会掉入陷阱,而且会是很深的陷阱,而且对于刚开始写java和数据库进行交互的人来说,这个错误是很容易犯并且很难找的,所以这里就分享一下了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐