What is wrong in this Java JDBC program? - java

What is wrong in this Java JDBC program?
I have written a method that takes a ResultSet and prints all of its records.
My SQL query is:
Set #counter := 0, #counterQty := 0, #counterAvb := 0, #counterIss := 0, #counterRep := 0 ,#counterDes := 0;
Select *
From (SELECT
(Select (#counter := (#counter + 1) ) ) 'Sr.No.',
testt.BookName,
testt.BookQty,
testt.Code,
testt.Available,
testt.Issued,
testt.Repair,
testt.Destroyed,
(#counterQty := #counterQty + testt.BookQty ) TotalQty,
(#counterAvb := #counterAvb + testt.Available ) TotalAvb,
(#counterIss := #counterIss + testt.Issued ) TotalIss,
(#counterRep := #counterRep + testt.Repair ) TotalRep,
(#counterDes := #counterDes + testt.Destroyed ) TotalDest
From (Select a.b_name BookName, a.b_qty BookQty, a.b_acc_id Code,
SUM(case when b.status='A' then 1 else 0 end) as Available,
SUM(case when b.status='I' then 1 else 0 end) as Issued,
SUM(case when b.status='R' then 1 else 0 end) as Repair,
SUM(case when b.status='D' then 1 else 0 end) as Destroyed
From tbl_book_info a left join tbl_books b on a.b_acc_id = b.accid
GROUP BY a.b_name, a.b_qty, a.b_acc_id order by a.b_acc_id
)testt
)Main;
When I am executing this query in MySQL Workbench, it returns:
+--------+--------------+---------+-------+-----------+--------+--------+-----------+----------+----------+----------+----------+-----------+
| Sr.No. | BookName | BookQty | Code | Available | Issued | Repair | Destroyed | TotalQty | TotalAvb | TotalIss | TotalRep | TotalDest |
+--------+--------------+---------+-------+-----------+--------+--------+-----------+----------+----------+----------+----------+-----------+
| 1 | Java book | 3 | 10001 | 0 | 0 | 1 | 2 | 3 | 0 | 0 | 1 | 2 |
| 2 | Cpp Book | 5 | 10002 | 3 | 1 | 0 | 1 | 8 | 3 | 1 | 1 | 3 |
| 3 | Cpp 1.17 | 5 | 10003 | 3 | 1 | 0 | 1 | 13 | 6 | 2 | 1 | 4 |
| 4 | Visual Basic | 4 | 10004 | 4 | 0 | 0 | 0 | 17 | 10 | 2 | 1 | 4 |
+--------+--------------+---------+-------+-----------+--------+--------+-----------+----------+----------+----------+----------+-----------+
4 rows in set (0.25 sec)
But when I am executing this query in Java and printing all data of ResultSet, it returns like:
1 2 3 4 5 6 7 8 9 10 11 12 13
+--------+--------------+---------+-------+-----------+--------+--------+-----------+----------+----------+----------+----------+-----------+
| Sr.No. | BookName | BookQty | Code | Available | Issued | Repair | Destroyed | TotalQty | TotalAvb | TotalIss | TotalRep | TotalDest |
+--------+--------------+---------+-------+-----------+--------+--------+-----------+----------+----------+----------+----------+-----------+
0 Cpp 1.17 5 10003 3 1 0 1 0 0 0 0 0
0 Cpp Book 5 10002 3 1 0 1 0 0 0 0 0
0 Java book 3 10001 0 0 1 2 0 0 0 0 0
0 Visual Basic 4 10004 4 0 0 0 0 0 0 0 0
+--------+--------------+---------+-------+-----------+--------+--------+-----------+----------+----------+----------+----------+-----------+
My question is:
Why it is giving zero (0) for column 1,9,10,11,12 and 13
Tables structure
create table if not exists tbl_book_info(
b_acc_id int(5) not null auto_increment,
b_name varchar(50) not null,
b_qty int(2) not null,
b_type varchar(30) not null,
b_auth1 varchar(50) not null,
b_auth2 varchar(50),
b_pub varchar(50) not null,
b_pages int(4) not null,
b_rack int(5) not null,
b_price Decimal(6,2) not null,
b_about text,
primary key(b_acc_id)
);
create table if not exists tbl_books(
accid int(5) references tbl_book_info.b_acc_id,
accno int(3),
status varchar(1) default "A",
primary key(accid,accno)
);
My code to print this:
Connection con = getDbConnObj();
Statement st = con.createStatement();
ResultSet rs = st.executeQuery( sql );
printRsLast(rs);
public void printRsLast(ResultSet rs){
/* +---1----+-----2--------+----3----+--4----+-----5-----+----6---+---7----+-----8-----+-----9----+----10----+----11----+----12----+-----13----+
| Sr.No. | BookName | BookQty | Code | Available | Issued | Repair | Destroyed | TotalQty | TotalAvb | TotalIss | TotalRep | TotalDest |
rs= +--------+--------------+---------+-------+-----------+--------+--------+-----------+----------+----------+----------+----------+-----------+
| 1 | Java book | 3 | 10001 | 1 | 0 | 0 | 2 | 3 | 1 | 0 | 0 | 2 |
|...........................................................................................................................................|
|...........................................................................................................................................|
|...........................................................................................................................................|
+--------+--------------+---------+-------+-----------+--------+--------+-----------+----------+----------+----------+----------+-----------+ */
String separator = " ";
try{
rs.beforeFirst();
int n=0;
p("$$$ RS Attr. are : \n\n Sr.No. | BookName | BookQty | Code | Available | Issued | Repair | Destroyed | TotalQty | TotalAvb | TotalIss | TotalRep | TotalDest , Row are...\n");
while(rs.next()){
n++;
String nm , m;
m = rs.getInt(1)+ separator + rs.getString(2)+ separator + rs.getInt(3)+ separator + rs.getInt(4)+ separator + rs.getInt(5)+ separator + rs.getInt(6)+ separator + rs.getInt(7)+ separator + rs.getInt(8)+ separator + rs.getInt(9)+ separator +
rs.getInt(10)+ separator + rs.getInt(11)+ separator + rs.getInt(12)+ separator + rs.getInt(13);
p(m+"\n");
}
p("\nTotal Rows = "+n);
} catch(Exception e){
p("\n!!! Excep in 'printRsLast(ResultSet rs), msg = '"+e.getMessage());
}
}
public Connection getDbConnObj() {
// Creating 'Connection' class' Reference Variable ...
Connection con = null;
String url = "jdbc:mysql://localhost:3306/librarydb";
String dbUname = "root";
String dbPass = "";
try {
Class.forName("com.mysql.cj.jdbc.Driver");
con = DriverManager.getConnection(url, dbUname, dbPass);
} catch (Exception e) {
con = null;
} finally {
return con;
}
}
I tried both the things ...
1)
sql = "Set #counter := 0...";
rs = st.execute(sql); // Execute this 'Set #counter...' Stmt first Than
sql = "Select * From...";
rs = st.executeQuery(sql); // Executing this 'Select * from...' Stmt to get the Tabular Data...
printRsLast(rs);
2)
sql = "Set #counter := 0...
....
....
)Main;"
rs = st.executeQuery(sql); // Executing these Entire Stmt to get the Tabular Data...
printRsLast(rs);
But Unfortunately , Both did not worked for me...

You haven't shown us how you've constructed the string sql in your Java code, so I'm going to have to guess.
It seems that sql contains your query from Select * onwards, without the line Set #counter := 0 .... I was able to reproduce your output if I set sql to this. Perhaps you've tried putting that Set line in the query as well and that generated an error so you took it out?
What you need to do instead is to execute the Set #counter := 0 ... line and then run the query. In other words, replace the lines
Connection con = getDbConnObj();
Statement st = con.createStatement();
ResultSet rs = st.executeQuery( sql );
printRsLast(rs);
with
Connection con = getDbConnObj();
Statement st = con.createStatement();
st.execute("Set #counter := 0 ...");
ResultSet rs = st.executeQuery( sql );
printRsLast(rs);
I made this modification to your code and it generated the output you wanted.

Related

attach string variable to ranked column values

i had help here to update a table column with values from a computed ranked column.how can i attach string variables to them such that instead of values like 1,2,3,4...they will be 1st,2nd, 3rd,4th..
i wrote this code :
//code create computed ranked column
String sql1 = SELECT COUNT(DISTINCT s2.Total) AS Rank from class1 s1
JOIN class1 s2 on (s1.Total<=s2.Total)
GROUP BY s1.ID order by s1.Name ASC;
pst = conn.prepareStatement(sql1);
rs = pst.executeQuery();
// attaching a string variable to the resultset
String type = rs.getString(2);
typ=Integer.parseInt(type);
String type1 = "";
if(typ==1){
type1="st";
}else if(typ==2){
type1="nd";
}else if(typ==3){
type1="rd";
}else if(typ>3){
type1="th";
}
//updating table column with the resultset
String sql = "";
while (rs.next()) {
sql = "update class1 set Position='"+rs.getString(2)+type1+"'"+" WHERE ID="+rs.getString(1);
pst=conn.prepareStatement(sql);
pst.execute();
but what this does is to repeat the result of the first row to all the rows..
| NAME | SCORE 1 | SCORE 2 | TOTAL | POSITION |
------------------------------------------------------------------------
| james | 10.0 | 24.0 | 34.0 | 1st |
| jimmy | 10.0 | 20.0 | 30.0 | 2st |
| josh | 10.0 | 19.0 | 29.0 | 3st |
how do i get it to work like
| NAME | SCORE 1 | SCORE 2 | TOTAL | POSITION |
------------------------------------------------------------------------
| james | 10.0 | 24.0 | 34.0 | 1st |
| jimmy | 10.0 | 20.0 | 30.0 | 2nd |
| josh | 10.0 | 19.0 | 29.0 | 3rd |
thank you.

Calculate/Determine Hours for Nightshift in mysql

Here is the table for the employee's logs:
And what I want is to generate the time ins and time out of employees. like this:
Can anyone help me for this? Any added logic or algorithm will be accepted.
This is one way. And it will work for day/night any shifts, provided, the first min(datetime) represent IN.
Rextester Sample
select t.enno
,max(datetime) as time_out
,min(datetime) as time_in
,time_to_sec(timediff(max(datetime), min(datetime) )) / 3600
as No_of_hours
from
(
SELECT
floor(#row1 := #row1 + 0.5) as day,
t.*
FROM Table4356 t,
(SELECT #row1 := 0.5) r1
order by t.datetime
) t
group by t.day,t.enno
;
Output
+------+---------------------+---------------------+-------------+
| enno | time_out | time_in | No_of_hours |
+------+---------------------+---------------------+-------------+
| 6 | 16.05.2017 06:30:50 | 15.05.2017 18:30:50 | 12,0000 |
| 6 | 17.05.2017 05:30:50 | 16.05.2017 18:10:50 | 11,3333 |
+------+---------------------+---------------------+-------------+
Explanation:
SELECT
floor(#row1 := #row1 + 0.5) as day,
t.*
FROM Table4356 t,
(SELECT #row1 := 0.5) r1
order by t.datetime
This query uses sequence to increment #row1 with 0.5, so you will get 1 1.5 2 2.5. Now if you just get the integer part of with with floor, you will generate sequece like 1 1 2 2. So this query will give you this output
+-----+------+---------------------+
| day | enno | datetime |
+-----+------+---------------------+
| 1 | 6 | 15.05.2017 18:30:50 |
| 1 | 6 | 16.05.2017 06:30:50 |
| 2 | 6 | 16.05.2017 18:10:50 |
| 2 | 6 | 17.05.2017 05:30:50 |
+-----+------+---------------------+
Now you can group by day and get max and min time.

How to select next record and previous record in SQLite?

I have been searching like forever
I am using min and max for the last and and first record but how do I get the next/ record? I have a column name rowid it is the pk and auto incremented by one every time a user registers
| rowid | Name |
| 1 | John |*
| 2 | Mark |
| 3 | Peter|
| 4 | Help |
so if I click the next button I wanted to select mark which is in rowid 2
| rowid | Name |
| 1 | John |
| 2 | Mark |*
| 3 | Peter|
| 4 | Help |
but if I click the next button twice I want to be in rowid 4
| rowid | Name |
| 1 | John |
| 2 | Mark |
| 3 | Peter|
| 4 | Help |*
how do I do that? by the way I don't have fixed rows since I have a registration function
so here's my code
JButton btnNextLast = new JButton(">>");
btnNextLast.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try{
String sQuery = "select * from accountinfo where rowid = (SELECT MAX(rowid) FROM accountinfo)";
PreparedStatement prst = connection.prepareStatement(sQuery);
ResultSet rs = prst.executeQuery();
lblSID.setText(rs.getString("sid"));
lblfirst.setText(rs.getString("last"));
lblLast.setText(rs.getString("first"));
lblmiddle.setText(rs.getString("middle"));
lblbirth.setText(rs.getString("birth"));
lblcontact.setText(rs.getString("contact"));
}catch(Exception qwe){
}
}
});
I've tried
select rowid
from accountinfo
where rowid >1
order by rowid
limit 1
but no luck
and if I remove order by rowid limit 1. It just show the next record which is 2 and never function again

I need help re-writing this method using a Java Array or ArrayList

I have a database table called trading_history which looks like this:
+----------+---------+---------+-----------+------------+
| table_id | item_id | user_id | item_type | phone |
+----------+---------+---------+-----------+------------+
| 1 | 4564704 | 629 | 2 | 3656284 |
| 2 | 4564705 | 629 | 1 | 3656284 |
| 3 | 4564773 | 569 | 1 | 8111111 |
| 4 | 4564792 | 351 | 2 | 0804609120 |
| 5 | 4564825 | 569 | 1 | 8111111 |
| 6 | 4564853 | 646 | 1 | 1111144 |
| 7 | 4564874 | 646 | 1 | 1111144 |
| 8 | 4564944 | 646 | 1 | 1111144 |
| 9 | 4564964 | 105 | 2 | 3614794 |
| 10 | 4564965 | 105 | 1 | 3614794 |
+----------+---------+---------+-----------+------------+
Fields table_id, and item_id are unique. The table records items sold by a user. Item_ids are sequential for each user, meaning that the top most item for a user is the item he sold first while the bottom most item represents the most recent item he sold.
From the above table, I want to periodically remove all items and leave only 20 most recent items sold by the user. That is, if a user has sold 100 items, I want to remove the 80 oldest items and leave him with 20. For those who have sold less than 20 in that period nothing will be removed.
I accomplished that by writing a SQL statement like this:
CREATE TABLE IF NOT EXISTS trading_history_archive LIKE trading_history;
INSERT INTO trading_history_archive
SELECT table_id, item_id , user_id,item_type,phone FROM trading_history
WHERE item_id NOT IN (
SELECT item_id
FROM trading_history as tdg
WHERE 20 > (
SELECT count(*)
FROM trading_history AS tdg1
WHERE tdg.user_id = tdg1.user_id
AND tdg.item_id > tdg1.item_id )
ORDER BY item_id DESC );
DELETE a FROM trading_history a INNER JOIN trading_history_archive b ON a.table_id = b.table_id;
However, this needs to be part of a Java application to be managed by the Scheduler. I tried creating a method using the SQL statements, but it looks clumsy and I fear SQL injection:
public class ArchiveTrading {
private final static Logger LOG = Logger.getLogger (ArchiveTrading.class);
private int sessionsArchived = 0;
.....
.....
.....
archiveTradingHistory(con, yymm);
.....
.....
private void archiveTradingHistory(Connection con, String yymm) {
try {
SqlUtil.runSqlUpdate(con, "CREATE TABLE IF NOT EXISTS trading_history_archive LIKE trading_history");
LOG.info("Finihsed creating table");
int inserted = SqlUtil.runSqlUpdate(con, "INSERT INTO trading_history_archive " +
" SELECT table_id, item_id , user_id,item_type,phone FROM trading_history "+
" WHERE item_id NOT IN ( "+
" SELECT item_id ( " +
" FROM trading_history as tdg " +
" WHERE 20 > ( "+
" SELECT count(*) "+
" FROM trading_history AS tdg1 "+
" WHERE tdg.user_id = tdg1.user_id "+
" AND tdg.item_id > tdg1.item_id ) "+
" ORDER BY item_id DESC ) ");
LOG.info("trading_history Inserted: " + inserted);
int deleted = SqlUtil.runSqlUpdate(con, "DELETE a FROM trading_history a INNER JOIN trading_history_archive b ON a.table_id = b.table_id");
LOG.info("trading_history Deleted: " + deleted);
} catch (NumberFormatException e) {
LOG.error(e.getMessage());
} catch (CustomDAOException e) {
LOG.error(e.getMessage());
}
}
.....
......
}
Someone help me improve this so I can survive work politics.

Usage of mysql variables in query in Spring Jdbc Template gives error

I have a requirement of picking top 2 students within each subject. Here is my table and the query which I am using to get that.
CREATE TABLE `students` (
`student` varchar(10) DEFAULT NULL,
`subject` varchar(10) DEFAULT NULL,
`marks` int(10) DEFAULT NULL
);
INSERT INTO students VALUES
('Deepak', 'Maths', 100),
('Neha', 'Maths', 90),
('Jyoti', 'Maths', 80),
('Ashwini', 'Maths', 70),
('Amit', 'Maths', 30),
('Sandeep', 'Maths', 95),
('Cinni', 'Maths', 86),
('Anand', 'Maths', 75),
('Deepak', 'Science', 100),
('Neha', 'Science', 90),
('Jyoti', 'Science', 80),
('Ashwini', 'Science', 70),
('Amit', 'Science', 30),
('Sandeep', 'Science', 95),
('Cinni', 'Science', 86),
('Anand', 'Science', 75),
('Deepak', 'History', 100),
('Neha', 'History', 90),
('Jyoti', 'History', 80),
('Ashwini', 'History', 70),
('Amit', 'History', 30),
('Sandeep', 'History', 95),
('Cinni', 'History', 86),
('Anand', 'History', 75);
mysql> SELECT * FROM students
+---------+---------+-------+
| student | subject | marks |
+---------+---------+-------+
| Deepak | Maths | 100 |
| Neha | Maths | 90 |
| Jyoti | Maths | 80 |
| Ashwini | Maths | 70 |
| Amit | Maths | 30 |
| Sandeep | Maths | 95 |
| Cinni | Maths | 86 |
| Anand | Maths | 75 |
| Deepak | Science | 100 |
| Neha | Science | 90 |
| Jyoti | Science | 80 |
| Ashwini | Science | 70 |
| Amit | Science | 30 |
| Sandeep | Science | 95 |
| Cinni | Science | 86 |
| Anand | Science | 75 |
| Deepak | History | 100 |
| Neha | History | 90 |
| Jyoti | History | 80 |
| Ashwini | History | 70 |
| Amit | History | 30 |
| Sandeep | History | 95 |
| Cinni | History | 86 |
| Anand | History | 75 |
+---------+---------+-------+
24 rows in set (0.00 sec)
mysql> Set character_set_connection=latin1;
Query OK, 0 rows affected (0.00 sec)
mysql> Set character_set_results=latin1;
Query OK, 0 rows affected (0.00 sec)
mysql> Set character_set_client=latin1;
Query OK, 0 rows affected (0.00 sec)
mysql> SET #rowcnt := 0; SET #grp := ''; SELECT d.* FROM (
-> SELECT
-> cs.*,
-> #rowcnt := IF(#grp != cs.subject, 1, #rowcnt + 1) AS rowcnt,
-> #grp := cs.subject
-> FROM (
-> SELECT * FROM students ORDER BY subject, marks DESC
-> ) cs
-> ) d
-> WHERE d.rowcnt < 3;
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
+---------+---------+-------+--------+--------------------+
| student | subject | marks | rowcnt | #grp := cs.subject |
+---------+---------+-------+--------+--------------------+
| Deepak | History | 100 | 1 | History |
| Sandeep | History | 95 | 2 | History |
| Deepak | Maths | 100 | 1 | Maths |
| Sandeep | Maths | 95 | 2 | Maths |
| Deepak | Science | 100 | 1 | Science |
| Sandeep | Science | 95 | 2 | Science |
+---------+---------+-------+--------+--------------------+
6 rows in set (0.00 sec)
mysql>
Now, everything works fine from the console, but when I execute the same query in Spring JdbcTemplate, it gives me error.
jdbcTemplate.query(query, new StudentRowMapper());
The query prints out to following which is exactly same as the query which I am using on command line.
SET #rowcnt := 0; SET #grp := ''; SELECT d.* FROM ( SELECT cs.*, #rowcnt := IF(#grp != cs.subject, 1, #rowcnt + 1) AS rowcnt, #grp := cs.subject FROM ( SELECT * FROM students ORDER BY subject, marks DESC ) cs ) d WHERE d.rowcnt < 3;
Here is the error which I get while running this:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 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 'SET #grp := ''; SELECT d.* FROM ( SELECT cs.*, ' at line 1
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.Util.getInstance(Util.java:386)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1054)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4190)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4122)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2570)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2731)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2818)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2157)
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2324)
at org.springframework.jdbc.core.JdbcTemplate$1.doInPreparedStatement(JdbcTemplate.java:646)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:589)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:639)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:668)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:676)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:716)
Just place the vars in the select like this
SELECT d.*
FROM
( SELECT cs.*, #rowcnt := IF(#grp != cs.subject, 1, #rowcnt + 1) AS rowcnt, #grp := cs.subject
FROM ( SELECT * FROM (select #rowcnt :=0, #grp :='') a,students ORDER BY subject, marks DESC ) cs ) d
WHERE d.rowcnt < 3;

Categories