In the code below using java, I am trying to get data from mysql between two choosed dates and load it into table jTable1 but the problem is when I run the data loads correctly but not until the second date.
For example, if first date is 2020-1-1 and second date is 2020-1-31 the data loads from the day of 1 to the day of 30 not until the day of 31. The last day is missing! And if I choose dates from 2020-01-01 to 2020-02-01 it loads from 2020-01-01 to 2020-01-31.
java.sql.Timestamp timestamp = new java.sql.Timestamp(jDateChooser5.getDate().getTime());
java.sql.Timestamp timestamp2 = new java.sql.Timestamp(jDateChooser6.getDate().getTime());
String sql2 = "SELECT sum(`msareffishmarket`.`Amount` ) FROM `manfz`.`msareffishmarket` \n"
+ "Where `msareffishmarket`.`place` = 'محل الأسماك' And ( `msareffishmarket`.`MsarefDate` between '" + timestamp + "' And '" + timestamp2 + "' ) "
+ " group by DATE(`msareffishmarket`.`MsarefDate`)";
stm2 = conn.prepareStatement(sql2);
rs2 = stm2.executeQuery(sql2);
// JOptionPane.showMessageDialog(this, rs.getDouble(4));
jTable3.setModel(DbUtils.resultSetToTableModel(rs2));
You are using your prepared statement incorrectly (though you are correct to think to use one). Consider this version of your code:
String sql = "SELECT MsarefDate, SUM(Amount) AS total FROM manfz.msareffishmarket ";
sql += "WHERE place = 'محل الأسماك' AND MsarefDate BETWEEN ? AND ? GROUP BY MsarefDate";
stm2 = conn.prepareStatement(sql);
stm2.setTimestamp(1, timestamp);
stm2.setTimestamp(2, timestamp2);
rs2 = stm2.executeQuery(); // do not pass the query string here
Edit:
Per the correct observations of #mangusta (see below), you should be using a date/timestamp range to search for your records. Assuming you wanted all records from January 2020, you should be using:
WHERE MsarefDate >= '2020-01-01' AND MsarefDate < '2020-02-01'
Related
I am trying to extract data from mysql tables according to timestamps like 'Top votes of the Month' and 'Top votes of the week'
This is mysql statement for collecting top vote of the week (week 4)
"SELECT * FROM studentid.questions WHERE vote IN (SELECT MAX(vote) FROM studentid.questions WHERE timestamp BETWEEN '"+currentYear+"-"+currentMth+"-19 00:00:00' AND '"+currentYear+"-"+currentMth+"-24 23:59:59');
This is mysql statement for collecting top vote of the month (may)
"SELECT * FROM studentid.questions WHERE vote IN (SELECT MAX(vote) FROM studentid.questions WHERE timestamp BETWEEN '"+currentYear+"-05-01 00:00:00' AND '"+currentYear+"-05-31 23:59:59')"
Somehow, the sql statement returns results OUTSIDE of the date ranges, for example, if in the month of may, there is a data with votes equal to another data in the month of february, it will display both of them, when it should only display from may...
sql results
The root cause of the problem you describe is probably due to the time zone difference between the server and your app, or from the way you are using parameters. If it's the latter you should change the code to use JDBC parameters as shown below:
First you compute the "from" and "to" timestamps in Java, and then you apply them:
Timestamp fromTS = ...
Timestamp toTS = ...
PreparedStatement ps = conn.createStatement(
"SELECT * " +
"FROM studentid.questions " +
"WHERE vote IN ( " +
" SELECT MAX(vote) FROM studentid.questions " +
" WHERE timestamp BETWEEN ? AND ?)"
);
ps.setTimestamp(1, fromTS);
ps.setTimestamp(2, toTS);
ResultSet rs = ps.executeQuery();
...
We have 3 to 4 environments with identical setup, each with multiple clustered application servers (WebSphere) and Oracle Supercluster databases.
The problem I am seeing seems to be happening in only one of the environments that too about 20% of the time.
We have
Two applications deployed to same application server cluster
Both applications use the same data source configured to use the Oracle database which is a Oracle Supercluster.
Following is the structure of the table in question
TABLE SESSION_TBL
(
ID NUMBER(12, 0) NOT NULL,
USER_ID VARCHAR2(256 BYTE) NOT NULL,
SESSION_ID VARCHAR2(60 BYTE) NOT NULL,
LOGIN_TIME TIMESTAMP(6) NOT NULL
)
Application 1 stores a record using JDBC
String sql = "Insert into SESSION_TBL " +
" (USER_ID, SESSION_ID, LOGIN_TIME ) " +
" values (?,?,SYSDATE)";
try
{
sessionId = getNewSessionId(userId);
st = conn.prepareStatement(sql);
st.setString(1, userId);
st.setString(2, sessionId);
int rows = st.executeUpdate();
}
After a few seconds, Application 2 executes the following code to look up the record inserted by the first application and compares with the current time
Statement st = null;
ResultSet result = null;
String sql = " Select * " +
" from SESSION_TBL " +
" where USER_ID = '" + userId + "' " +
" and SESSION_ID = '" + sessionId + "' ";
try {
st = conn.createStatement();
result = st.executeQuery(sql);
if(!result.next()) { // We have no data, need to expire the session
logger.debug("End hasSessionExpired()");
return true;
}
else {
logger.debug("SessionInfo:ResultSet not null");
}
// Get the time user logged in
// java.sql.Timestamp
Timestamp database_date = result.getTimestamp("LOGIN_TIME"); // get date from db
long databaseDate = database_date.getTime(); // Convert to UNIX time
// Get the current time from the database, so we are getting the time
// from the same sources to compare
// See the code below for this function
long currentTime = getCurrentTimeFromDB (conn);
// Both time values would be in milli seconds
long diffSecs = (currentTime - databaseDate)/1000;
logger.info ("db:" + databaseDate + " now:" + currentTime + " diffSecs:" + diffSecs);
Code to get the current time from the database
public static long getCurrentTimeFromDB () {
.
.
// Using SYSDATE. We only need precision upto seconds
String s = "SELECT SYSDATE NOW FROM DUAL";
rs = statement.executeQuery(s);
if (rs.next()) {
Timestamp dbTime = rs.getTimestamp("NOW");
currentTime = dbTime.getTime();
}
return currentTime;
}
In about 1 of 5 or so executions, I see the current time to be earlier than the time of the record creation (login time). When this happens I see an output of the debug statement like the following:
db:1538793249000 now:1538793023000 diffSecs:-226
db:1538793249000 now:1538793023000 diffSecs:-202
db:1538793249000 now:1538793023000 diffSecs:-225
Seems like about 200+ seconds earlier
If you notice one thing the data type of the column (LOGIN_TIME) is a Timestamp and I am using SYSDATE to populate it. However, I am also using SYSDATE to get the time from DUAL. Of the 4 environments we have, this is happening in one and not always. Is there something wrong in the code or is it possible that the database Oracle super cluster) is actually returning a date that is not correct.
I thought I would put an answer in case someone else runs into a similar problem. As folks have suggested (in the comments) that the cluster nodes times could be out of sync. We have 2 nodes in the cluster, one node was ahead (of the current time) by a couple of minutes. One could detect if the time is out of sync, by running a SYSDATE query against each node.
I did a SQL query in Java as follows:
"SELECT A.ID_MACHINE, A.HEURODATAGE, A.COMPTEUR, B.LIBELLE_IDMACHINE, C.LIBELLE_STATUT, C.CODE_COULEUR FROM ROXJAVA.MACH0004 A " +
"JOIN ROXJAVA.MACH0003 B ON A.ID_MACHINE = B.ID_MACHINE " +
"JOIN ROXJAVA.MACH0002 C ON B.CODE_MACHINE = C.CODE_MACHINE " +
"WHERE A.ID_MACHINE = ? AND A.HEURODATAGE BETWEEN '?' AND '?' AND A.CODE_STATUT = C.CODE_STATUT AND C.CODE_COULEUR = ? " +
"ORDER BY A.HEURODATAGE DESC";
In my WHERE it finds "Heurodatage" which must contain a time and a date with this format:
'2018-07-03 09:30:00.000'
I then want to retrieve the results of this query with the help of a method that takes into account the different attributes that I need to replace the? in my request.
But now I can not determine the type of my dates.
I'm getting "type not match" when I try to run with a String.
If the column is a date column, you want to pass in a date type:
PreparedStatement ps = ...;
ps.setDate(N, java.sql.Date.valueOf(your_date_value));
where it would be best if your_date_value is a java.time.LocalDate, but could also be parsed from a String (in a valid format).
The query works fine but since I must test my project several time and I dont want always to adjust the arrivaltime table to the current time I would integrate a string time to the query but I am getting the following error
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ':56,'%H:%i') and name LIKE 'hbf'' at line 1
The time must include only the hours as well minutes digits.
String time = "12:56:00";
PreparedStatement preparedTime = con
.prepareStatement("SELECT route from arrivaltimes INNER JOIN stops"
+ " ON arrivaltimes.stop_id=stops.stop_id "
+ "WHERE weekday = '"
+ day
+ "'"
//+ " and time_format(arrivaltime,'%H:%i')= time_format(curtime() ,'%H:%i') and name LIKE '"
+ " and time_format(arrivaltime,'%H:%i')= time_format("+ time+ ",'%H:%i') and name LIKE '"
+ stop_name + "'");
ResultSet rsArrivaletime = preparedTime.executeQuery();
When using PreparedStatement, NEVER CONCATENATE STRINGS TO GET THE QUERY, EVER. Pass the proper time as java.sql.Time or java.sql.Timestamp as parameters.
String sql =
"SELECT route FROM arrivaltimes INNER JOIN stops"
+ " ON arrivaltimes.stop_id = stops.stop_id"
+ " WHERE weekday = ?"
+ " and arrivaltime = ?"
+ " and name LIKE ?";
PreparedStatement preparedTime = con
.prepareStatement(sql);
preparedTime.setString(1, day);
//preparing the proper time using java.util.Calendar
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 12);
cal.set(Calendar.MINUTE, 56);
cal.set(Calendar.SECOND, 0);
//create an instance of java.sql.Time
//Calendar#getTime returns an instance of java.util.Date
//Date#getTime returns the time in millis (long)
Time time = new Time(cal.getTime().getTime());
//setting the time
preparedTime.setTime(2, time);
preparedTime.setString(3, stopname);
ResultSet rs = preparedTime.executeQuery();
i have a table "queue_in_progress" whose structure is like the following :
I want to update the DATE_TIME_TOKEN_TAKEN , CE_PK , Service_status of the table . For this , I have the following code :
String sqlQuery = "UPDATE queue_in_progress\n" +
"SET CE_PK="+ce_pk+" ,SERVICE_STATUS=1 \n" +
"WHERE CATEGORY_PK="+Category_PK+" AND TOKEN_NO="+ Token_PK+" "
+ " AND SERVICE_COUNTER="+service_counter+" AND SERVICE_CENTER_PK="+service_center+" ;";
java.util.Date utilDate = new Date(); // Convert it to java.sql.Date
java.sql.Date date = new java.sql.Date(utilDate.getTime());
PreparedStatement stmt = con.prepareStatement(sqlQuery);
stmt.setDate(1, date);
success = stmt.executeUpdate();
But the success flag is returning -1 and the table is not updated . What is the problem ? What can I do to fix this problem ?
I don't see DATE_TIME_TOKEN_TAKEN=? in your query (the bind parameter), I think you wanted
String sqlQuery = "UPDATE queue_in_progress SET DATE_TIME_TOKEN_TAKEN=?, "
+ "CE_PK=" + ce_pk
+ ", SERVICE_STATUS=1 WHERE CATEGORY_PK="
+ Category_PK
+ " AND TOKEN_NO="
+ Token_PK
+ " AND SERVICE_COUNTER="
+ service_counter + " AND SERVICE_CENTER_PK=" + service_center;
OR if you want DATE_TIME_TOKEN_TAKEN to ALWAYS hold Current Time value, you can Set it on your Database side, no need to set it in your code.
ALTER TABLE queue_in_progress
MODIFY DATE_TIME_TOKEN_TAKEN DEFAULT CURRENT_TIMESTAMP;