使用 JDBC 在 SQL 中的日期之间搜索?
Posted
技术标签:
【中文标题】使用 JDBC 在 SQL 中的日期之间搜索?【英文标题】:Searching between dates in SQL with JDBC? 【发布时间】:2013-10-25 07:33:39 【问题描述】:我目前正在编写一个 Java Swing 应用程序,它从 MYOB 数据库文件中读取数据并在表中显示某些信息。我已经能够成功生成所需的 SQL 语句,但在添加日期之间搜索的功能时遇到了麻烦(我们的数据库非常大,所以我们试图限制结果)。下面是我的一个查询示例(用 Java 编写):
rs = stmt.executeQuery("SELECT sales.InvoiceNumber, sales.ShipToAddress, sales.Date "
+ "FROM sales, customers "
+ "WHERE sales.CardRecordID = customers.CardRecordID "
+ "AND customers.Name = 'Cash Sales' "
+ "ORDER BY sales.ShipToAddress ASC, sales.Date DESC"
+ ";");
我有两个日期(它们实际上是 Java 中的字符串,但格式为 dd/MM/yyyy)。
我尝试在 WHERE
中使用另一个 AND
子句和 BETWEEN
语句,但我从 JDBC [MYOB ODBC]Error getting the literal value of right operand.
收到以下错误
实际陈述如下:
rs = stmt.executeQuery("SELECT sales.InvoiceNumber, sales.ShipToAddress, sales.Date "
+ "FROM sales, customers "
+ "WHERE sales.CardRecordID = customers.CardRecordID "
+ "AND customers.Name = 'Cash Sales' "
+ "AND sales.Date BETWEEN " + sdate + " AND " + edate + " "
+ "ORDER BY sales.ShipToAddress ASC, sales.Date DESC"
+ ";");
有人能帮我找出正确的语法吗?这是缺少的最后一个功能。
编辑:sdate
和 edate
的当前值分别为 25/10/2013,因为它们默认为今天的日期。我已经设置了我正在测试的虚拟文件,以确保它将提供具有此日期范围的数据。另外为澄清起见,我希望搜索日期包含在内。
【问题讨论】:
sdate 和 edate 的值是什么? 当前日期为 25/10/2013(这将是日期的标准格式,也总是 dd/MM/yyyy) 我不确定,但也许您需要将字符串转换为日期。比如... BETWEEN CAST( '" + sdate + "' AS DATE)
等等
【参考方案1】:
在日期前后使用引号:
rs = stmt.executeQuery("SELECT sales.InvoiceNumber, sales.ShipToAddress, sales.Date "
+ "FROM sales, customers "
+ "WHERE sales.CardRecordID = customers.CardRecordID "
+ "AND customers.Name = 'Cash Sales' "
+ "AND sales.Date BETWEEN '" + sdate + "' AND '" + edate + "' "
+ "ORDER BY sales.ShipToAddress ASC, sales.Date DESC"
+ ";");
或者使用准备好的语句可能更安全(例如,如果日期来自不受信任的输入):
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
java.util.Date startDate = formatter.parse(sdate);
java.util.Date endDate = formatter.parse(edate);
PreparedStatement pstmt = connection.prepareStatement("SELECT sales.InvoiceNumber, sales.ShipToAddress, sales.Date "
+ "FROM sales, customers "
+ "WHERE sales.CardRecordID = customers.CardRecordID "
+ "AND customers.Name = 'Cash Sales' "
+ "AND sales.Date BETWEEN ? AND ? "
+ "ORDER BY sales.ShipToAddress ASC, sales.Date DESC");
pstmt.setDate(1, new java.sql.Date(startDate.getTime()))
pstmt.setDate(2, new java.sql.Date(endDate.getTime()))
between 运算符包含在内,但如果您的数据库字段实际上是时间戳,则假定没有时间的日期为时间 00:00:00.000。因此,在这种情况下,为了使您的日期包含在内,您可以在结束日期上增加一天。从技术上讲,它还将包括第二天(00:00:00.000 小时)的第一个 instant,但根据您的应用程序,这可能就足够了。
否则,您可以在“开始日期”上使用>=
,在“结束日期加一天”上使用<
:
"sales.Date >= '" + sdate + "' AND sales.Date < '" + edatePlusOne + "' "
【讨论】:
我能够通过添加''
并将日期格式更改为yyyy/MM/dd
来解决问题。我现在唯一的问题是 BETWEEN 查询不是 date INCLUSIVE 使用>=
和<=
会更好吗?编辑:它实际上是包容性的,对不起,我有一个代码错误。一切正常
@gRnt BETWEEN
包括在内。您确定您的销售日期实际上是DATE
而不是TIMESTAMP
(所以它包含时间)?如果它是TIMESTAMP
,则DATE
被提升为TIMESTAMP
(如yyyy-MM-dd 00:00:00.00000
,因此介于00:00:00.00000
之后的条件将不包括与上限日期相同的项目。请注意,某些数据库使用术语 DATE
来表示实际上(在 SQL 标准和 JDBC 中)TIMESTAMP
。【参考方案2】:
看来您需要用这种格式表示日期:
select * from table where datefield between '2006-10-01' 和 '2006-11-30'
看看here,别忘了谷歌是你的朋友! :)
【讨论】:
【参考方案3】:Class.forName("com.mysql.jdbc.Driver");
connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/hospitall","root","");
PreparedStatement ps=connection.prepareStatement("select * from patient where patientid='"+txtpatientid.getText()+"'");
Statement stm=connection.createStatement();
ResultSet rs=ps.executeQuery();
if(rs.next())
String patientid=txtpatientid.getText();
String str="select * from patient where patientid='"+patientid+"'";
ResultSet result=stm.executeQuery(str);
【讨论】:
您不应该使用字符串连接。这为 SQL 注入之类的东西打开了大门。请改用ps.setXXX(...)
。以上是关于使用 JDBC 在 SQL 中的日期之间搜索?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 MS Access 在 C# 中的两个日期之间进行搜索
如何通过 SQL 语句从两个特定日期(由用户指定)之间的数据库表中获取数据?