我正在尝试使用PreparedStatement构建一个查询,我认为当我使用PreparedStatement时会出现问题,因为它什么也没有返回。然后我尝试传递直接的SQL查询,它是成功的。 同样的查询我在Oracle SQL Developer中运行,它也取得了成功。
我需要知道我的代码有什么问题。
当使用PreparedStatement设置参数时,我的想法是sql查询正在构建的错误。
我在这里使用Oracle作为后端。
public List<Hotel> getAvailableHotelsDA(ReservationDetails resevationDetails) throws SQLException, ParseException
{
List<Hotel> hotelList = new ArrayList<Hotel>();
int idCountry = resevationDetails.getIdCountry();
int idState = resevationDetails.getIdState();
String query = "SELECT h.idHotel , h.Name , h.Description FROM hotel h"+
" INNER JOIN contract c ON h.idHotel = c.idHotel"+
" INNER JOIN country cn ON h.idCountry = cn.idCountry"+
" INNER JOIN state st ON cn.idCountry = st.idCountry"+
" WHERE c.startDate <= TO_DATE(?,'yyyy-MM-dd') "+
" AND c.endDate >= TO_DATE(?,'yyyy-MM-dd') "+
" AND c.isCurrentContract=?"+
" AND h.idState = ?"+
" AND h.idCountry = ?"+
" GROUP BY (h.idHotel , h.Name , h.Description)";
PreparedStatement prepStatement = null;
ResultSet resultSet = null;
try
{
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
format.setLenient(false);
Date checkIn = format.parse(resevationDetails.getCheckInDate());
Date checkOut = format.parse(resevationDetails.getCheckOutDate());
connection = DBUtility.getConnection();
//connection = DBUtility.getMySQLConnection();
prepStatement = connection.prepareStatement(query);
int count = 0;
prepStatement.setDate(++count, convertFromJAVADateToSQLDate(checkIn));
prepStatement.setDate(++count, convertFromJAVADateToSQLDate(checkOut));
prepStatement.setInt(++count, CONTRACT_STATE.CURRENT.getValue());
prepStatement.setInt(++count, idState);
prepStatement.setInt(++count, idCountry);
//prepStatement = connection.prepareStatement("SELECT h.idHotel , h.Name , h.Description FROM hotel h INNER JOIN contract c ON h.idHotel = c.idHotel INNER JOIN country cn ON h.idCountry = cn.idCountry INNER JOIN state st ON cn.idCountry = st.idCountry WHERE c.startDate <= TO_DATE('2015-02-25','yyyy-MM-dd') AND c.endDate >= TO_DATE('2015-03-05','yyyy-MM-dd') AND c.isCurrentContract=1 AND h.idState = 1 AND h.idCountry = 1 GROUP BY (h.idHotel , h.Name , h.Description)");
resultSet = prepStatement.executeQuery();
Hotel hotel;
while(resultSet.next())
{
hotel = new Hotel();
hotel.setHotelID(resultSet.getInt("idHotel"));
hotel.setName(resultSet.getString("Name"));
hotel.setDescription(resultSet.getString("Description"));
hotelList.add(hotel);
}
}
catch(SQLException ex)
{
System.out.println("Error : SQL Exception : Method : getAvailableHotels ");
ex.printStackTrace();
throw ex;
}
finally
{
DBUtility.close(resultSet, prepStatement, connection);
}
return hotelList;
}
答案 0 :(得分:1)
如果要绑定Date
,则拨打to_date
是没有意义的。 to_date
不接受date
作为输入,它只接受varchar2
。如果您传入date
,Oracle必须首先隐式地将date
转换为varchar2
,然后将varchar2
传递给to_date
以获得字符串转换回date
。隐式date
到varchar2
转换将使用您的会话nls_date_format
。如果这种情况与您传入to_date
的显式格式掩码不匹配,则您会收到错误消息,或者您将获得date
;期待。
由于您绑定了Date
,因此您的查询应该类似于
" WHERE c.startDate <= ? "+
" AND c.endDate >= ? "+
如果您要忽略startDate
或endDate
中的时间组件,您可能希望trunc
日期(可能涉及创建一些基于函数的索引)。< / p>
答案 1 :(得分:0)
我使用以下方法转换日期和解析日期而不使用 to_date ,这次成功
private java.sql.Date convertFromDateStringToSQLDate(String dateString)
{
java.sql.Date sqlDate = null;
try
{
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date dateNotFormat;
dateNotFormat = sdf.parse(dateString);
sdf.applyPattern("dd-MMM-yyyy");
String dateFormatString = sdf.format(dateNotFormat);
DateFormat formatter = new SimpleDateFormat("dd-MMM-yyyy");
Date dateFormat = (Date)formatter.parse(dateFormatString);
if (dateFormat != null)
{
sqlDate = new java.sql.Date(dateFormat.getTime());
}
System.out.println(sqlDate);
}
catch (ParseException e)
{
e.printStackTrace();
}
return sqlDate;
}
这是查询和绑定......
String query = "SELECT h.idHotel , h.Name , h.Description FROM hotel h"+
" INNER JOIN contract c ON h.idHotel = c.idHotel"+
" INNER JOIN country cn ON h.idCountry = cn.idCountry"+
" INNER JOIN state st ON cn.idCountry = st.idCountry"+
" WHERE c.startDate <= ? "+
" AND c.endDate >= ? "+
" AND c.isCurrentContract=?"+
" AND h.idState = ?"+
" AND h.idCountry = ?"+
" GROUP BY (h.idHotel , h.Name , h.Description)";
PreparedStatement prepStatement = null;
ResultSet resultSet = null;
try
{
connection = DBUtility.getConnection();
//connection = DBUtility.getMySQLConnection();
prepStatement = connection.prepareStatement(query);
int count = 0;
prepStatement.setDate(++count, convertFromDateStringToSQLDate(resevationDetails.getCheckInDate()));
prepStatement.setDate(++count, convertFromDateStringToSQLDate(resevationDetails.getCheckOutDate()));