in my project i have created a system to book a room.
My problem concerns the booking of a room on the same date.
This is the DB about reservation.
id_book,login,email,typeroom,numroom,arrivaldate,departuredate.
And this is the code to check if a room is available in a period:
try {
Class.forName("com.mysql.cj.jdbc.Driver");
// out.println("driver loaded");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/Hotel?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC","root" ,"123456789");
out.println("Connect");
Statement st = con.createStatement();
Statement stmt = con.createStatement();
out.println("connection successfull");
String check = ("SELECT res1.id_prenotazione, res1.typeroom, res1.arrivaldate, res1.departuredate\n" +
"FROM reservation res1, reservation res2\n" +
"WHERE ( res1.typeroom = res2.typeroom ) \n" +
"AND (res1.arrivaldate <= res2.departuredate)\n" +
"AND (res2.arrivaldate <= res1.departuredate)");
String check1 = ("SELECT count(*) FROM reservation WHERE arrivaldate");
ResultSet rs2 = stmt.executeQuery(check);
ResultSet rs3 = stmt.executeQuery(check1);
if( rs2 != rs3) {
int rs = st.executeUpdate("insert into reservation (login,email,typeroom,numroom,arrivaldate,departuredate)values ('"+login+"','"+email+"','"+typeroom+"','"+numroom+"','"+arrivaldate+"','"+departuredate+"')");
}
String getResultSet = ("SELECT count(*) FROM reservation WHERE arrivaldate ='"+arrivaldate+"'");
String rs1 = ("SELECT count(*) FROM reservation WHERE arrivaldate");
if (getResultSet != rs1) {
int i=st.executeUpdate("DELETE FROM reservation WHERE id_prenotazione ='"+id_prenotazione+"'");
}
The problem is that in this way I keep recording the same rooms with the same date, how can i solve?
I did not get your question fully. The part that I understood is you obviously don't want to overbook rooms on a given date.
If it is the case, while showing available rooms, you can fire count(*) query for that date. There is no need to any update operation at that time.
It is at the time of actual booking, you need to handle the overbooking either by taking proper lock or writing query in a way that no. of rooms does not go below 0.
Related
I'm trying to make a sql query builder type program that uses user input data to build custom queries for the table
so far i have
public int checkBetweenDates() throws SQLException{
String t1 = "2015-07-08"; //or later some user input variable
String t2 = "2015-07-09";//or later some user input variable
String id = "22 03 E7 99";//or later some user input variable
int rowCount = -1;
//Statement stmt = null;
String dateChoice = "select count(*) "
+ "from dancers "
+ "where ts between (t1) and (t2)"
+ "and id = (id)"
+ "values (?)";
Connection conn = DriverManager.getConnection(host, username, password);
System.out.println("Connected:");
PreparedStatement preparedStmt = (PreparedStatement) conn.prepareStatement(dateChoice);
preparedStmt.setString (1, t1);
// preparedStmt.setString (2, t2);
// preparedStmt.setString (3, id);
// stmt = conn.createStatement();
ResultSet rs = preparedStmt.executeQuery(dateChoice);
try {
rs = preparedStmt.executeQuery(dateChoice);
rs.next();
rowCount = rs.getInt(1);
System.out.println(rowCount);
}
catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally {
rs.close();
preparedStmt.close();
}
return rowCount;
}
So it connects and everything fine but it doesnt execute the query saying something wrong with the sql syntax for values(?,?,?)
Any help would be awesome thanks guys!!
Carl
Try this, Changes in query and in setting prepared statement parameters,
public int checkBetweenDates() throws SQLException{
String t1 = "2015-07-08"; //or later some user input variable
String t2 = "2015-07-09";//or later some user input variable
String id = "22 03 E7 99";//or later some user input variable
int rowCount = -1;
//Statement stmt = null;
String dateChoice = "select count(*) "
+ "from dancers "
+ "where ts between ? and ?"
+ "AND id = ?";
Connection conn = DriverManager.getConnection(host, username, password);
System.out.println("Connected:");
PreparedStatement preparedStmt = (PreparedStatement) conn.prepareStatement(dateChoice);
preparedStmt.setString (1, t1);
preparedStmt.setString (2, t2);
preparedStmt.setString (3, id);
// stmt = conn.createStatement();
ResultSet rs = preparedStmt.executeQuery(dateChoice);
try {
rs = preparedStmt.executeQuery(dateChoice);
rs.next();
rowCount = rs.getInt(1);
System.out.println(rowCount);
}
catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally {
rs.close();
preparedStmt.close();
}
return rowCount;
}
Share the exact error if doesn't work for you.
Change this:
String dateChoice = "select count(*) "
+ "from dancers "
+ "where ts between (t1) and (t2)"
+ "and id = (id)"
+ "values (?)";
According to the database syntax that you are using. For example if you using a webserver with Mysql go and type the query to see where the typo is. (if you using mysql it needs dancers to every table)
First, you seem to have edited this method many times to try fix the problem, which has left it in a confused state.
remove the "values (?)" from the sql statement, it does not belong here, it seems to be left over from a prepared insert statement.
call preparedStmt.executeQuery() with zero arguments, you have already supplied it with the sql string and only call it ONCE, you assign a value to rs twice.
your sql statement should contain exactly three question marks, try
select count(*) from dancers where ts between ? and ? and id = ?
next call preparedStmt.setString() three times to supply values t1, t2 and id.
Also, remember to close the connection object in the finally block.
Sorry if the title is not precise.
I am using a custom class to get data from a SQLite database.
For example:
the method below is supposed to return list of users, which are members of a certain department.
Each user in the USER table has a column with id of the department he belongs to.
At the moment I am getting all the users and then comparing their department IDs to the targetID of the department I am looking for.
Is there a way to get just the set of users that have a particular department ID, so that I don't have to check each one's department id?
private List<User> getDepartmentMembers(int targetID) {
List<User> members = new ArrayList<User>();
Connection c = null;
Statement statement = null;
try {
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:TheatroData.sqlite");
c.setAutoCommit(false);
statement = c.createStatement();
ResultSet rs = statement.executeQuery( "SELECT * FROM USERS;" );
while ( rs.next() ) {
int id = rs.getInt(Constants.ID_KEY);
if (id == targetID ){
User tmp = null;
int position = rs.getInt(Constants.POSITION_KEY);
if (position == Constants.DEPARTMENT_HEAD)
tmp = new DepartmentHead();
else if (position == Constants.DEPARTMENT_MANAGER)
tmp = new DepartmentManager();
else if (position == Constants.DEPARTMENT_MEMBER);
tmp = new GruntUser();
tmp.setID(id);
tmp.setName(rs.getString(Constants.NAME_KEY));
tmp.setPosition(position);
tmp.setUsername(rs.getString(Constants.USERNAME_KEY));
tmp.setLastname(rs.getString(Constants.SURNAME_KEY));
tmp.setDepartment(targetID);
tmp.setPassword(rs.getString(Constants.PASS_KEY));
members.add(tmp);
}
}
rs.close();
statement.close();
c.close();
} catch ( Exception e ) {
System.err.println( e + " -in getDepartmentMembers" + e.getClass().getName() + ": " + e.getMessage());
}
return members;
}
I was thinking I need something like this:
ResultSet rs = statement.executeQuery( "SELECT * FROM USERS where department = ?;", targetID );
In an ideal world, you could do it as you wrote:
ResultSet rs = statement.executeQuery( "SELECT * FROM USERS WHERE department = ?;", targetID );
But, executeQuery from JDBC does currently not provide the possibility for argument binding. So you have to use "Prepared Statements".
Instead of
statement = c.createStatement();
ResultSet rs = statement.executeQuery( "SELECT * FROM USERS;" );
do:
prepared = c.prepareStatement("SELECT * FROM USERS WHERE department = ?;");
prepared.setString(1, targetID);
ResultSet rs = prepared.executeQuery();
When you need more than one parameter, you can use a different syntax for replacing it, for example "?001". See SQLite Documentation: C/C++ Interface Section 5.
Also remove the Java coding for your own selection of the right department.
Since the CluelessStudent presented a different solution, involving string concatenation, I want to say the following:
I would definitively discourage string concatenation! You always
should use argument binding and not string concatenation! String
concatenation is a huge security risk, since it can be used for so
called "SQL injection attacks". See Wikipedia: SQL Injection
Yes you pratcially answered your own question. You can also do like this.
String query = "SELECT * FROM USERS where department = (?)";
PreparedStatement statement = c.prepareStatement(sql);
statement.setInt(1, targetId);
ResultSet rs = statement.executeQuery();
while(rs.next()){
//you get only records that have id = targetId
}
//close rs, statement and connection!!!
I was just passing a wrong statement. The correct way:
ResultSet rs = statement.executeQuery( "SELECT * FROM USERS where department = "+targetID+";");
Im working with Sql and java.
This works in sql:
use mybank
Select * from Account
inner join CustomerAccount on accountid = id
where customerid = 18
In java i write this:
String sql = ("Select * From Account inner join CustomerAccount on accountid = id where customerid =?;");
try (Connection con = myDbManager.getConnection())
{
PreparedStatement ps = con.prepareStatement(sql);
ps.setInt(1, customer.getId());
Statement st = con.createStatement();
ResultSet rs = st.executeQuery(sql);
customer.getId gives me 18.
but i get this error;
Incorrect syntax near '?'.
The problem is here:
ResultSet rs = st.executeQuery(sql);
You're using Statement#executeQuery(String sql) which is inherited from Statement interface. You should use PreparedStatement#executeQuery.
In short, change that line to:
ResultSet rs = ps.executeQuery();
^ parameter-less
And remove this Statement variable from your code, it will just confuse you and future readers of the code:
PreparedStatement ps = con.prepareStatement(sql);
ps.setInt(1, customer.getId());
//Statement st = con.createStatement();
^ this generates confusion
Also, you should remove the semicolon in your SQL statement when executing it form Java:
String sql = "Select *"
+ " From Account"
+ " inner join CustomerAccount"
+ " on accountid = id"
+ " where customerid = ?";
SQL-Queries in Java don't use the ';':
String sql =( "Select * From Account inner join CustomerAccount on accountid = id where customerid =?");
I have this code;
String sql = "UPDATE Players SET Losses=Losses+1 WHERE UUID='" + p.getUniqueId() + "';";
stmt.executeUpdate(sql);
How can I get the current Losses for a specific Player p?
SELECT query will return it, but what's your real question?
String sql ="SELECT column_name,column_name FROM table_name WHERE column_name ="" ;";
I would use a Select for Update, and something like this -
String query = "SELECT Losses FROM Players FOR UPDATE "
+ "Players SET Losses=Losses+1 WHERE UUID=?";
ps = conn.prepareStatement(query,
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_UPDATABLE);
ps.setString(1, p.getUniqueId());
ResultSet rs = ps.executeQuery();
int losses = 0;
if (rs.next()) {
losses = rs.getInt("Losses");
}
You can get the losses like the following. Seems really trivial, guess you are an absolute beginner.
String sql = "SELECT Losses FROM Players WHERE UUID='" + p.getUniqueId() + "';";
ResultSet rs = stmt.executeQuery(sql);
int losses = -1;
if(rs.next()) {
losses = rs.getInt("Losses");
}
You'd have to make a SELECT statement. Like SELECT losses FROM Players WHERE UUID='"+p.getUniqueId()+"';";
Then use Statement's executeQuery() which returns a ResultSet. You can use an iterator to extract the data from the ResultSet object.
This question already has answers here:
ResultSet exception - before start of result set
(6 answers)
Closed 9 years ago.
I am getting the error Before start of result set I thought that I had to use next() on the ResultSet before retrieving data from the ResultSet ?
public void getPersonsOrders(String firstName){
Connection con = connect();
try{
Statement s = con.createStatement();
s.executeUpdate("use stl;");
ResultSet rs1 = s.executeQuery("select personID from person where first_name = " +"'"+firstName+"'"+";"); //get persons ID no.
ResultSet rs2 = s.executeQuery("select * from orderr where personID = "+rs1.getInt(1)+";"); //use ID no. to
rs2.next();
for(int i = 1; i < 4; i++){ //retrive order
System.out.println(rs2.getInt(i));
}
}
catch(SQLException e){
System.out.println("3" +e.getMessage());
}
}
You should execute
rs1.next();
before
ResultSet rs2 = s.executeQuery("select * from orderr where personID = "+rs1.getInt(1)+";");
Remember that you should close opened resources.
Regards.
You can use the following mechanism.
resultSet=s.executeQuery("select personID from person where first_name = " +"'"+firstName+"'"+";");
if (resultSet!= null)
{
do
{
//You can code your business logic here by getting data from db like:
System.out.println(resultSet.getString("first_name"));
} while (resultSet.next());
You don't call rs1.next() before reading from it with rs1.getInt(1).
As an aside, you can do this with a single SQL statement with a join are follows:
SELECT orderr.* FROM orderr JOIN person ON orderr.personID = person.personID WHERE person.first_name = ?
You should also use a java.sql.PreparedStatement like this:
PreparedStatement preparedStatement = connection.prepareStatement("SELECT orderr.* FROM orderr JOIN person ON orderr.personID = person.personID WHERE person.first_name = ?");
preparedStatement.setString(1, firstName);
ResultSet resultSet = preparedStatement.executeQuery();
The database will cache the query plan, which will help performance plus it will prevent SQL injection attacks.