在 java 中设置参数时,准备好的语句查询构建不起作用
Prepared Statement query building not working when the parameters are setting in java
我正在尝试使用 PreparedStatement 构建查询,但我认为在使用 PreparedStatement 时出现问题,因为它 return 什么都没有。然后我尝试传递直接 sql 查询,它成功了。
同样的查询我是 运行 在 Oracle SQL Developer 中,它也成功了。
我需要知道我的代码有什么问题。
我的想法有问题sql正在构建查询,当使用 PreparedStatement 设置参数时。
这里我使用的是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;
}
如果你要绑定一个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
日期(这可能涉及创建一些基于函数的索引) .
我使用下面的方法在没有使用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()));
我正在尝试使用 PreparedStatement 构建查询,但我认为在使用 PreparedStatement 时出现问题,因为它 return 什么都没有。然后我尝试传递直接 sql 查询,它成功了。 同样的查询我是 运行 在 Oracle SQL Developer 中,它也成功了。
我需要知道我的代码有什么问题。
我的想法有问题sql正在构建查询,当使用 PreparedStatement 设置参数时。
这里我使用的是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;
}
如果你要绑定一个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
日期(这可能涉及创建一些基于函数的索引) .
我使用下面的方法在没有使用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()));