在java中设置参数时,Prepared Statement查询构建不起作用

时间:2015-03-02 04:09:40

标签: java sql oracle prepared-statement

我正在尝试使用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;

}

2 个答案:

答案 0 :(得分:1)

如果要绑定Date,则拨打to_date是没有意义的。 to_date不接受date作为输入,它只接受varchar2。如果您传入date,Oracle必须首先隐式地将date转换为varchar2,然后将varchar2传递给to_date以获得字符串转换回date。隐式datevarchar2转换将使用您的会话nls_date_format。如果这种情况与您传入to_date的显式格式掩码不匹配,则您会收到错误消息,或者您将获得date ;期待。

由于您绑定了Date,因此您的查询应该类似于

" WHERE c.startDate <= ? "+
" AND c.endDate >= ? "+

如果您要忽略startDateendDate中的时间组件,您可能希望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()));