I am attempting to go through my Access database with Java in order to check if a date range falls in between another date range to avoid duplicate reservations. I am running into an SQL error that says "ResultSet is Closed". I believe it is because I am using two resultSet in order to check two different dates withing one while loop. Here is the code:
String date1Query = "SELECT checkIn FROM Reservation WHERE roomLocation LIKE '" + room + "'";
String date2Query = "SELECT checkOut FROM Reservation WHERE roomLocation LIKE '" + room + "'";
ResultSet date1RS = statement.executeQuery(date1Query);
ResultSet date2RS = statement.executeQuery(date2Query);
while (date1RS.next()) {
date1 = date1RS.getDate("checkIn");
date2 = date2RS.getDate("checkOut");
dateCheckBool = dateCheck.dateCheck(date1, date2, checkIn, checkOut);
if (dateCheckBool == true)
break;
}
How else can I format this to achieve the same functionality (being able to check the input dates by the user against the already existing dates in the database) but not get an error? If this is not clear enough what I am trying to do I will try to clarify further upon request. Thank you!
EDIT: As requested here is the dateCheck code:
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class dateCheck {
public boolean dateCheck(Date date1, Date date2, String date3, String
date4){
DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
Date dateCheck1;
Date dateCheck2;
boolean dateRange1 = false;
boolean dateRange2 = false;
try {
dateCheck1 = dateFormat.parse(date3);
dateCheck2 = dateFormat.parse(date4);
if(dateCheck1.before(date1) || dateCheck1.after(date2))
dateRange1 = false;
else
dateRange1 = true;
if(dateCheck2.after(date2))
dateRange2 = false;
else
dateRange2 = true;
} catch (ParseException e) {
e.printStackTrace();
}
if(dateRange1 == false && dateRange2 == false)
return false;
else
return true;
}
}
Why fiddling around when SQL alone can give you the result?
If you wish to know whether a reservation is already in place, just ask the database.
SELECT id as result From reservations
Where (
([RoomLocation] like ?)
And (
(? between [checkin] and [checkout])
OR (? between [checkin] and [checkout])
)
);
in your java:
statement.setString(1,room);
statement.setDate(2,date1);
statement.setDate(3,date2);
..execution..
If there are any reservations you will receive the reservation id. If not null. You can also put above SQL within another select command and return true or false value.
If you are having issues with incompatible date formats, you might have to format the date and pass it as string.
Ps: answering from mobile, double check the SQL for typos.
Related
I'm getting this error and I don't why I tried the statement on workbench and it worked.
I'm looking also to improve my dates subtracting code basically I'm getting deadline from the table and I'm subtracting from today's date.
public boolean checkLessThanWeek(User userWhoWantsToExtendDeadline,BorrowedBook book) throws ParseException {
try {
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT Deadline FROM library_students.borrowedcopies WHERE LenderToID =" + "'" + userWhoWantsToExtendDeadline.getId()+ "'"+"And Barcode="+"."+book.getbookID());
if (rs.next()) {
SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd");
Date deadline = format.parse(rs.getString(1));
Date date=new Date();
String today=format.format(date.getDate());
date = format.parse(today);
long milliseconds=date.getTime()-deadline.getTime();
long days = milliseconds / (1000 * 60 * 60 * 24);
System.out.print(days);
}
rs.close();
return true;
} catch (SQLException ex) {
ex.printStackTrace();
return false;
}
}
It is most likely because book.getbookID() returns null and because you for some reason have a dot (.) before it in your Sql. Besides this it is preferred to have a parameterized Sql statement using ? and also basic error handling is a good thing.
if (userWhoWantsToExtendDeadline == null || book == null || book.getbookID() == null {
//throw exception perhaps or log?
return false;
}
String query = "SELECT Deadline FROM library_students.borrowedcopies WHERE LenderToID = ? AND Barcode = ?";
Statement stmt = con.createStatement(query);
stmt.setInt(1, userWhoWantsToExtendDeadline.getId());
stmt.setString(2, book.getbookID());
ResultSet rs = stmt.executeQuery();
Note that I assumed your first parameter is an int and the second one is a String but of course ths might need to be changed
I do simple alarm and i need show alert if value from column 0 == today.
Calendar cal = new GregorianCalendar();
int day = cal.get(Calendar.DAY_OF_MONTH);
try {
File currDir= new File ("Baza.db");
String sc = currDir.getAbsolutePath();
sc = sc.substring(0, sc.length());
String url = "jdbc:sqlite://"+sc;
Connection conn = DriverManager.getConnection(url);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT Day FROM Month");
jTable1.setModel(DbUtils.resultSetToTableModel(rs));
if(jTable1.getValueAt(0, 0).equals(day)){
JOptionPane.showMessageDialog(null, "Do your question!");
}
} catch (SQLException e) {
JOptionPane.showMessageDialog(null, e);
}
I trying use method getColumn, getColumnModel and getSelectedColumn but but nothing compared my calculations..
Your day variable is of type int and jTable1.getValueAt(0, 0) returns an Object hence both are of different type and will always return false upon comparison.
As you want to compare the equality of them as string, hence you should change your comparison from this,
if(jTable1.getValueAt(0, 0).equals(day)){
to,
if(String.valueOf(jTable1.getValueAt(0, 0)).equals(String.valueOf(day))){
Or, you may parse the value in Jtable column to int and then compare the integer value like this,
if(Integer.parseInt(jTable1.getValueAt(0, 0).toString()) == day){
However, I'll prefer the first way to compare as string, as second way can run into NumberFormatException
This post is related to my previous post.
Recently i have a project in which i should send an string and two datetime field to SQL Server 2014 and get some fields.(Locaitions)
So i created two DatePicker, that End User can select the date he want.
And instance of a Calender.
Well,with help of my friends here, i used this till now :
Calendar finalCalendar = Calendar.getInstance();
int fDay = datePicker2.getDayOfMonth();
int fMonth = datePicker2.getMonth();
int fYear = datePicker2.getYear();
finalCalendar.set(Calendar.YEAR, fYear);
finalCalendar.set(Calendar.MONTH, fMonth);
finalCalendar.set(Calendar.DAY_OF_MONTH, fDay);
finalCalendar.set(Calendar.HOUR, 0);
finalCalendar.set(Calendar.MINUTE, 0);
finalCalendar.set(Calendar.SECOND, 0);
finalCalendar.set(Calendar.MILLISECOND, 0);
SimpleDateFormat fSimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
setFinalDate(fSimpleDateFormat.format(finalCalendar.getTime()));
Well, when i pass it to my SP,it gives me :
java.lang.NumberFormatException: Invalid int: "18 12:00:00.000"
That 18 is the day i have chosen, and 12 as you see is the time i have set to 0,also Minute,Second and mili second.
And i try below code to see if the time the code returns is true or not :
Toast.makeText(getApplicationContext(), getFinalDate(), Toast.LENGTH_SHORT).show();
and it shows correct time that i have chosen from DatePicker.
And when i insert this format of time in SQL Server Management Console it works properly.
And i pass this to SQL Server Stored Procedure from android as below.
callableStatement.setDate(3, java.sql.Date.valueOf(getFinalDate()));
I tried different ways in google.
Different formats of SimpleDateFormat.
I think somewhere i make a mistake.
Any help will appreciate.
And I have a ConnectionHelper Class that works correctly.
I Instance of this.
And call CallableStatement.
CallableStatement callableStatement;
ConnectionHelper connectionHelper1 = new ConnectionHelper();
try {
callableStatement = connectionHelper1.getMyConnection().prepareCall("{call SpSelectTrackVehiclePath(?, ?, ?)}");
callableStatement.setString(1, IMEArrayAdapter.getItem(listView.getCheckedItemPosition()));//IMEArrayAdapter in below will explain,gives the first field of SP.
callableStatement.setTimestamp(2, new java.sql.Timestamp(startCalendar.getTimeInMillis()));
callableStatement.setTimestamp(3, new java.sql.Timestamp(finalCalendar.getTimeInMillis()));
callableStatement.addBatch();
callableStatement.executeBatch();
ResultSet resultSet = callableStatement.executeQuery();
if(resultSet.next()) {
do {
Toast.makeText(getApplicationContext(), "Bingoo", Toast.LENGTH_SHORT).show();
spOut.add(resultSet.getDouble("Latitude"));
i++;
} while (resultSet.next());
}else
{
Toast.makeText(getApplicationContext(), "Error ! ", Toast.LENGTH_SHORT).show();
}
} catch (SQLException e) {
e.printStackTrace();
}
The first Field of this is String that i get from another Table of DB.
Like this(In onCreate Method) :
ConnectionHelper connectionHelper = new ConnectionHelper();
try {
Statement statement = connectionHelper.getMyConnection().createStatement();
ResultSet resultSet = statement.executeQuery("select Id from Device");
while(resultSet.next())
{
String ime;
ime = resultSet.getString("Id");
IMEIs.add(ime); //This is ArrayList<String> Type
IMEArrayAdapter.getItemViewType(R.id.listView); //get the listView id in XML,
listView.setAdapter(IMEArrayAdapter); //with this line it set Adapter and all id shows in my ListView
}
connectionHelper.closeConnection();
} catch (SQLException e) {
e.printStackTrace();
connectionHelper.closeConnection();
}
And In MSSQL Server Management when i execute this SP with fiels Like this :
IMEI : xxxxxxx
firsDate : 2015-11-18 12:00:00:00
lastDate : 2015-11-24 12:00:00:00
It returns the values.
I execute like this is MSSQL Server Management Studio :
USE [xxxxx]
GO
DECLARE #return_value int
EXEC #return_value = [dbo].[xxxxxx]
#DeviceId = N'xxxxxxxxxxxx',
#DateTimeBegin = N'2015-11-18 00:00:00:000',
#DateTimeEnd = N'2015-11-24 00:00:00:000'
SELECT 'Return Value' = #return_value
GO
I copy the execute code of SP in MSSQL Server Management Studio.(above)
I can not see what your getFinalDate() is returning I guess the String yyyy-MM-dd hh:mm:ss, the correct way on java.sql.Date.valueOf should be yyyy-MM-dd, do not include the time
but since you have the Calender object why not do something like this (avoid all parsing)
callableStatement.setDate(3, new java.sql.Date(finalCalendar.getTimeInMillis()));
important is that your column on database is of type DATE
if it is TIMESTAMP or DATETIME you should use:
callableStatement.setTimestamp(3, new java.sql.Timestamp(finalCalendar.getTimeInMillis()));
and yes in this case passing string in valueOf, the string format should be yyyy-MM-dd hh:mm:ss
EDIT: This has nothing to do with original question but a follow up on CallableStatement.
If the callable statement is a query (return resultset), you need to registrer output and you do not addBatch the code would be something like this:
callableStatement = connectionHelper1.getMyConnection().prepareCall("{call SpSelectTrackVehiclePath(?, ?, ?,?)}");
callableStatement.setString(1, IMEArrayAdapter.getItem(listView.getCheckedItemPosition()));//IMEArrayAdapter in below will explain,gives the first field of SP.
callableStatement.setTimestamp(2, new java.sql.Timestamp(startCalendar.getTimeInMillis()));
callableStatement.setTimestamp(3, new java.sql.Timestamp(finalCalendar.getTimeInMillis()));
callableStatement.registerOutParameter(4, java.sql.Types.INTEGER);
ResultSet resultSet = callableStatement.executeQuery();
I ran into problem when my query returns result and I cannot check the next row.
//here i assume that only "regular" is correct room type
public boolean checkAvalibility(String roomType, String checkInDate, String checkOutDate ) throws SQLException{
database db = new database();
db.connect();
this.roomType = roomType;
if(roomType!="regular"){
System.out.println("please select correct room type");
return false;
}
myStmt = db.myConn.prepareStatement("select * from Rooms where "
+ "RoomType = ?");
myStmt.setString(1, roomType);
myRs = myStmt.executeQuery();
boolean val = myRs.next();
while(val){
if(roomType.equals(myRs.getString("RoomType"))){
System.out.println("correct room type");
isType = true;
}
if(isType == true){
int roomNumber = myRs.getInt("idRooms");
if(checkDateAvailability(checkInDate, checkOutDate, roomNumber)==true){
return true;
}
else{
return false;
}
}
}
System.out.println();
return false;
}
this code here
private boolean checkDateAvailability(String checkInDate,String checkOutDate, int roomNumber) throws SQLException{
database db = new database();
db.connect();
myStmt = db.myConn.prepareStatement("select idRooms, CheckIn, CheckOut from Rooms where "
+ "CheckIn=? AND RoomType=?");
myStmt.setString(1, checkInDate);
myStmt.setString(2, roomType);
myRs = myStmt.executeQuery();
boolean val = myRs.next();
while(val){
//calcDateBeetween simply takes check-in date which is in database and current check-out date converts them to integer value and compares the difference
if(calcDateBetween(checkOutDate, myRs.getString("CheckIn")) <=0 ){
System.out.println("You can book the room");
return true;
}
else{
System.out.println("Dates occupied");
return false;
}
}
if(val==false){
System.out.println("room is available for booking date is empty");
return true;
}
else{
System.out.println("i have no idea of what im doing");
}
return false;
}
As a pre-requirement, let's say I want to have only two rows and I don't need new records. If I send check-IN(!) date which matches the one in database (in Check-in column) then everything works fine, and I have print out saying that date is occupied. But if I send check-in value ex. 23-01-2015 and check-out 03-02-2015 it does not go to calcDateBetween() method, probably assuming that if query was empty then the table can be updated and I have a printout that dates are available for booking. What can be the solution in this situation and why it does not compare dates in second case?
Thanks !
There are a couple of issues here. Instead of
boolean val = myRs.next();
while(val){
write
while(myRs.next()) {
Otherwise, you're not checking each time whether there are more rows; you're just using the same true or false value each time.
Also, within your while loop, you have return true; and return false; - and one of these is going to run each time. That will make your method end, and your loop won't run again. You probably don't want these return statements in there.
Quick question. I got a code below, which checks with a database whether a given ID is available in the database, if so, it retrieves all attendance histories for the ID, otherwise if the ID didn't exist in the database it should display an error message. The code I got however, always says that the record has been attached, and then displays the error message as well regardless whether the ID exists or not. I think I probably have to change the order of the code or such? Could you please advise?
JButton button = new JButton("Submit");
button.addActionListener(new ActionListener() {
#SuppressWarnings("unused")
public void actionPerformed(ActionEvent arg0) {
String studentID = textField.getText();
try {
Statement st = con.con.createStatement();
ResultSet rs = st.executeQuery("SELECT StudentID, date FROM attendance WHERE StudentID ="+textField.getText());
while ( rs.next() ) {
String student = rs.getString("StudentID");
String date = rs.getString("date");
System.out.println(student+"");
System.out.println(date);
}
JOptionPane.showMessageDialog(frmAttendanceHistory, "Attendance has been registered.");
frmAttendanceHistory.setVisible(false);
if (!rs.next()) {
JOptionPane.showMessageDialog(frmAttendanceHistory, "A record for the given Student ID doesn't exist");
}
}
catch (SQLException e) {
JOptionPane.showMessageDialog(frmAttendanceHistory, "Attendance couldn't be registered. Please try again!");
e.printStackTrace();
}
}
});
You're repeatedly calling rs.next() until it returns false (as otherwise you'll never get out of the while loop) - then you're calling rs.next() again. Why would you expect it to return true then?
I suspect you want something like:
if (rs.next()) {
String student = rs.getString("StudentID");
String date = rs.getString("date");
System.out.println(student+"");
System.out.println(date);
JOptionPane.showMessageDialog(frmAttendanceHistory,
"Attendance has been registered.");
frmAttendanceHistory.setVisible(false);
} else {
JOptionPane.showMessageDialog(frmAttendanceHistory,
"A record for the given Student ID doesn't exist");
}
You're doing a second rs.next, which would go to a second record if there was one. If there's only one (which is already consumed further up in your app), then it fails giving you a success followed by a failure.
while ( rs.next() ) {
followed by
if (!rs.next()) {
Doesn't make any sense as the if will always execute. Your loop will continue until rs.next() returns false.