简体   繁体   中英

Prepared Statement query building not working when the parameters are setting in java

I am trying to build a query by using PreparedStatement and i think something goes wrong when i used PreparedStatement because it return nothing. Then i tried passing direct sql query and it was success. And same query i was run in Oracle SQL Developer and ,it was also success.

I need to know what is wrong with my code.

My Idea is something wrong sql query is building, when the parameters are set using PreparedStatement.

Here i am using Oracle as the back end.

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;

}

If you are going to bind a Date , it makes no sense to call to_date . to_date does not accept a date as an input, it only accepts a varchar2 . If you pass in a date , Oracle has to first implicitly cast the date to a varchar2 then pass the varchar2 to to_date in order to have the string converted back into a date . The implicit date to varchar2 conversion will use your session's nls_date_format . If that happens not to match the explicit format mask you're passing in to to_date , you'll either get an error or you'll get a date you don't expect.

Since you are binding a Date , your query should just be something like

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

If there are time components in startDate or endDate that you want to ignore, you probably want to trunc the date (which may involve creating some function-based indexes).

i used below method to convert date and parse date without using to_date and it was success this time

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;
} 

This is the query and binding...

    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()));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM