1. 程式人生 > >java操作mysql時執行帶有日期語句的誤區

java操作mysql時執行帶有日期語句的誤區

最近在寫伺服器端的一些介面,在用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和資料庫進行互動的人來說,這個錯誤是很容易犯並且很難找的,所以這裡就分享一下了。

相關推薦

java操作mysql執行帶有日期語句誤區

最近在寫伺服器端的一些介面,在用java對mysql進行含有日期資訊的查詢的時候,遇到了一些問題,分享一下 。 首先把資料庫中的一個用於使用者簽到的表的程式碼部分貼出來:create table signUpInfo ( phoneNum nvarchar(11) not

如何停止mysql正在執行的sql語句或是操作

在執行一些sql語句的時候,有時候可能會使mysql的cpu佔用爆漲,出現其它的應用無法使用的情況,這時候就要去停止正在執行的語句,如何不執行mysql restart的情況下,只把佔用cpu多的語句kill掉呢,使用如下的方法就可以:1.cli模式下登入mysqlmysql

javamysql之間的時間日期類型傳遞

兩個 其他 方案 entity 最優解 都是 nan set mat mysql(版本:5.1.50)的時間日期類型如下: datetime 8bytes xxxx-xx-xx xx:xx:xx 1000-01-01 00:00:00到9999-12-31 23:59:59

nevicat 監控資料庫 跟蹤 mysql 網站執行的 SQL 語句日誌

開啟navicat,執行SQL語句(要選定資料庫)  SHOW VARIABLES LIKE "general_log%" 如果日誌是OFF,說明沒有開啟日誌記錄,可以使用以下語句開啟 SET GLOBAL general_log = 'ON'&nb

Java專案啟動執行指定方法的幾種方式

很多時候我們都會碰到需要在程式啟動時去執行的方法,比如說去讀取某個配置,預載入快取,定時任務的初始化等。這裡給出幾種解決方案供大家參考。 1. 使用@PostConstruct註解 這個註解呢,可以在Spring載入這個類的時候執行一次。來看一下下方程式碼。

BareTail工具檢視Mysql實時執行的Sql語句

最近給客戶開發了基於Asp.Net mvc5 +Mysql+EF的專案,但是在EF裡無法看到Mysql執行的語句之前也找到一些監控Mysql的軟體但一直沒有用起來,現在又遇到了問題即在EF裡Mysal的查詢沒有結果而在Mysql裡沒有問題因為不知道EF生成的Mysql語句所以不知道是不是Sql的問題於是決定必

Java--類載入執行方法順序

class HelloA { public HelloA() { System.out.print("A"); } { System.out.p

eclipse中java操作mysql資料庫注意事項

1. 下載mysql JDBC驅動:例如mysql-connector-java-5.1.12(pudn上有); 2. 在eclipse裡的專案中建立lib目錄,把mysql-connector-java-5.1.12-bin-jar拷貝到這個目錄中,然後在專案的build

myBatis 操作 mysql,使用 like 關鍵進行模糊查詢的方法

我嘗試了以下三種方式:  一、 like '%#{mkName}%' 這種方式,myBatis直接報錯,說引數的數量不匹配。 二、 like '%'||#{mkName}||'%' 這種方式不報錯,但是查詢出來的結果是不是對的。比如,對於 mkName這個欄位,資料庫中只有 “小學”  這個值,但是當

JAVA操作Excel文字自適應單元格的寬度設定方法

      使用JAVA操作Excel通常都使用JXL,方法很簡單網上也有很多的教程,然後往往一些細節性的問題卻導致我們這些Programmer苦惱不已。這兩天幫一個朋友做一個Excel表格自動生成的小軟體,就遇到的類似的問題。       問題描述:通過Java向Exce

使用Tomcat操作MySQL遇到的問題

1.JSP中沒有匯入java.sql包 頁面上會出現JasperException:Unable to compile class for jsp(無法編譯JSP類),此時需要匯入sql包 2.

Mysql 一次性執行多條語句的實現

1.mysql資料庫預設情況下,mysql_query()是一次只執行一條語句。 #include "stdafx.h" #include <mysql.h> #include <string> using namespace std

java 操作mysql的建立資料庫及資料的增刪改查

1.用java建立資料庫,但是這種動態建立資料庫是非主流的。一般不會這樣操作。 import java.sql.*; public class Test { public static void main(String[] args) throws

java 操作mysqljava連線mysql資料庫並查詢資料

做java開發不可避免要處理資料庫,所以這裡寫篇用jdbc來連線mysql的文章,java是一種高效能,通用的語言 。這使得它適合於編寫高效的ETL生產程式碼和計算密集型的機器學習演算法。 主要內容包括: 1、java連線mysql 2、java查詢my

記錄在使用java操作mongodb的錯誤

1.報錯資訊為:org.bson.codecs.configuration.CodecConfigurationException: Can’t find a codec for class [Ljava.lang.String; 原因是mongodb中的

JAVA連線MySQL常見的錯誤解決方法

程式中連線mysql資料庫時,常常會出現如下異常 java.lang.ClassNotFoundException: com.mysql.jdbc.Driver      at java.net.URLClassLoader$1.run(URLClassLoader.j

C# 操作MYSQL 部分中文亂碼問題

在專案上,發現向MySql插入中文資料,有時候就是出錯。 報錯資訊: Incorrect string value: '\xE6\xB9\xA7\xE5\x93\xA5...' for column 'content' at row 1 但是大部分的中文都是沒有問題的,一

設置mysql執行沒where條件的sql語句提醒

RoCE water mark pro 是否 http images mysq ext 查看mysql是否開啟更新sql語句沒有where的檢測開關,on表示開啟,off表殼關閉 設置命令 通過執行沒有where的Sql語句來驗證設置mysql在執行沒where條件的sql

【Stimulsoft Reports Java教程】在執行使用MySQL資料庫建立報表

下載Stimulsoft Reports Java最新版本 此示例專案顯示如何使用MySQL欄位建立新報表並提取MySQL資料庫資訊。 首先,您需要建立一個新報表並新增MySqlDatabase。在StiMySqlDatabase類的建構函式中,您應該設定資料庫名稱,別名和連線字串。 p

Python連線MySQL資料庫執行sql語句的引數問題

由於工作需要,今天寫了一個Python小指令碼,其中需要連線MySQL資料庫,在執行sql命令時需要傳遞引數,結果出問題了。在網上查了一下,發現有以下幾種方式傳遞引數: 一.直接把sql查詢語句完整寫入字串 try: connection = MySQLdb.connect(user