String query = "SELECT sum(Cardhundred)FROM Dialog"; [duplicate] - java

This question already has an answer here:
How to retrieve sum of a column of data from the database?
(1 answer)
Closed 4 years ago.
Currently trying to get sum of the integers of a column called Cardhundred, I does not proceed the answer, can somebody suggest me an idea to get the total of all integers in my column?
I want to get the sum from a column in access database, the column from which I want to get the sum, has all integers value not double or float, and I have done some code for that which gives me no result, it means the text field which supposed to display the result is empty.
This is my code:
if(showtotal.isSelected()) {
try {
Connection conn = DriverManager.getConnection("jdbc:ucanaccess://E:\\Mydb.accdb");
Statement st = conn.createStatement();
String query = "SELECT sum(Cardhundred)FROM Dialog";
ResultSet rs=st.executeQuery(query);
if(rs.next()) {
String total=rs.getString("sum(Cardhundred)");
showdate.setText(""+total+"");
}
} catch(Exception e){ }
}

There are two ways to solve this: use the column index (rather than the name) then you don't need to worry about the name of the expression:
int total = rs.getInt(1);
The column numbering in JDBC starts with 1, not with 0 as with arrays in Java.
Alternatively, use a column alias in your query:
String query = "SELECT sum(Cardhundred) as total_number FROM Dialog";
Then use that alias to get the value:
int total = rs.getInt("total_number");

Related

Java pagination issue print Printwriter

I tried to do a pagination in Java using PrintWriter. I used this as model: https://www.javatpoint.com/pagination-in-servlet.
As you can see in the example code is done in order to work with 3 pages and 5 elements each page.
out.print("<a href='ViewServlet?page=1'>1</a> ");
out.print("<a href='ViewServlet?page=2'>2</a> ");
out.print("<a href='ViewServlet?page=3'>3</a> ");
int total=5;
I don't think it makes any sense to copy all my code since reading from database works.. I just want to have 1 element on each page and have as many pages as elements was found.
So I use
String query = "select * from tabL where name like CONCAT( '%',?,'%') limit "
+ (start-1)+","+total;
with 1 for start and 1 for total..
ResulSet will have size 1 but if I use this
out.print("<a href='ViewServlet?page=1'>1</a> ");
out.print("<a href='ViewServlet?page=2'>2</a> ");
out.print("<a href='ViewServlet?page=3'>3</a> ");
It prints other elements as well.
So please help how could be done to have as many pages as elements are found and 1 element each page.
Do I need to have a select without limit and use the size of resulset obtained with that, is there a better solution ?
PS: someone please explain me how if I put limit with 1,1 ResulSet has size 1 but it can print 3 elements at least.
I would need to know at least the exact number of elements which were retrieved even with limit 1.
Thank you.
To find the total count you can use a count-query:
String countQuery = "select count(*) from tabL where name like CONCAT( '%',?,'%')";
When you execute this query with the same parameter as the query for the data you will get a ResultSet with one row and one column.
You can retrieve it with
Connection con = ...; // you probably already have a Connection
PreparedStatement ps = con.prepareStatement(countQuery);
ps.setString(1, name); // the name pattern that you're searching for
ResultSet rs = ps.executeQuery();
int count = 0;
if (rs.next()) {
count = rs.getInt(1);
}

Building PreparedStatement in Java With Variable Number of Columns for Inserting Data into Database [duplicate]

This question already has answers here:
How to insert values in a table with dynamic columns Jdbc/Mysql
(2 answers)
Closed 5 years ago.
What is a good design pattern to achieve this without endless code?
Given the scenario whereby the user may input 1...100 columns, maybe 23 one time, 32 on another insert, and 99 fields on another insert etc. All of which may be different fields each time too.
The PreparedStatement in Java needs to know what column names to enter first, how many ?'s to put into the values part of the INSERT query, the data types of the database field names to ensure the correct setInt and setString etc are entered.
For less than around 10 columns, you can kind of get around this challenge with the following logic;
1) If variableEnteredForFieldName is not null, then append to the relevant parts of the query in the form of a String builder type setup;
fieldName_1
?
2) Do the same for all entered field names
3) Strip out the final trailing , that will naturally be present in both the field names and the ?s
4) Create the PreparedStatement
5) Run through the same input parameters again to determine of the variableEnteredForFieldName is not null, if not null, then run a setInt or setString based on the known data type that the database requires and set this to the correct index number for the ?s.
As long as the query builder logic and the query filler logic have the names/values in the correct order in part 1 and part 2, then all works well. It does however mean duplicating the entire code that relates to this logic, one for generating the SQL to use when creating the PreparedStatement and another for filling the PreparedStatement.
This is manageable for a small number of input parameters, but this soon gets unmanageable for larger number of input parameters.
Is there a better design pattern to achieve the same logic?
The code below is an outline of all of the above for reference;
String fieldName1 = request.getParameter("fieldName1");
String fieldName2 = request.getParameter("fieldName2");
//Build Query
String fieldNames = "";
String fieldQuestionMarks = "";
if (fieldName1 != null) {
fieldNames = fieldNames + " FIELD_NAME_1 ,";
fieldQuestionMarks = fieldQuestionMarks + " ? ,";
}
if (fieldName2 != null) {
fieldNames = fieldNames + " FIELD_NAME_2 ,";
fieldQuestionMarks = fieldQuestionMarks + " ? ,";
}
//Trim the trailing ,
fieldNames = fieldNames.substring(1, fieldNames.length() - 1);
fieldQuestionMarks = fieldQuestionMarks.substring(1, fieldQuestionMarks.length() - 1);
try {
String completeCreateQuery = "INSERT INTO TABLE_NAME ( " + fieldNames + " ) VALUES ( " + fieldQuestionMarks + " );";
Connection con = DriverManager.getConnection(connectionURL, user, password);
PreparedStatement preparedStatement = con.prepareStatement(completeCreateQuery);
int parameterIndex = 1;
//Fill Query
if (fieldName1 != null) {
preparedStatement.setString(parameterIndex, fieldName1);
parameterIndex++;
}
if (fieldName2 != null) {
preparedStatement.setInt(parameterIndex, Integer.parseInt(fieldName2));
parameterIndex++;
}
}
As you can see, it's do-able. But even with just 2 optional fields, this code is huge.
The way I see it, if user is able to omit any of the columns from the list, then all columns are optional, and can be safely set to NULL during an insert. Therefore, all you need is one prepared statement with the "monster" INSERT, with all columns listed; then during the actual insert operation, you loop though the user-provided data, setting values for the columns provided, and calling setNull() for omitted columns. You'll need to maintain a structure somewhere (your DAO class most likely) mapping column names to their order in the SQL statement.

How to pass array of strings dynamically to SQL "IN" clause in Java? [duplicate]

This question already has answers here:
PreparedStatement IN clause alternatives?
(33 answers)
Closed 9 years ago.
I have a array of Strings "String[]" with certain values. I want to pass that array dynamically to SQL "IN" clause something like:
Select * from Employee where emp_name in (?);
Here "?" has to replaced with String Array. I want to do this in Java Class. I tried with
Array array = conn.createArrayOf("VARCHAR", new Object[]{"1", "2","3"});
pstmt.setArray(1, array);
But it is not working and getting exception "SQLFeatureException".
Thanks!!!
Basically the field emp_name is not an array but a VARCHAR so when you set a value for it, it must be a String. So having only 1 ? in the query represents a single possible value for emp_name. You would have to list as many ?'s as the length of the array and substitute these individually with their values.
Assuming that empNames is a String[], you could do this to prepare the query:
StringBuilder query = new StringBuilder("Select * from Employee where emp_name in (");
for (int i = 0; i < empNames.length; i++) {
if (i > 0) {
query.append(",");
}
query.append("?");
}
query.append(")");
and this to set the individual values behind the ?'s:
for (int i = 0; i < empNames.length; i++) {
pstmt.setString(i+1, empNames[i]);
}
We can appy Select batching to resolve your problem. Reference:
link
You can create the query with IN clause by iterating the String array using StringBuilder.
I would recommend that don't get into complexity of using Arrays.toString() unless you really need that. There will not be much difference in the performance since both are needed to iterate the array to create the String literal.
In my approach we can have a good control over iteration of the array adding the single quote and comma etc.

How can i get another string from select query?

I want to get string from column no. 4 from my database to check user privileges.
Can I use rs.getString(index) to get data from column no.4?
I want to check user´s privileges...so if the column data is equal 4, the page will be redirected to AdminControlPanel.jsp
BUT, this code doesn´t work :(
String user=request.getParameter("login");
String pass=request.getParameter("password");
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/android","root","root");
Statement st=con.createStatement();
ResultSet rs=st.executeQuery("select * from users where login='"+user+"' and password='"+pass+"'");
String p = rs.getString(4);
int count=0;
while(rs.next()){
count++;
}
if(count>0 && p == "4"){
// out.println(rs);
response.sendRedirect("AdminControlPanel.jsp");
}
else{
out.println("aaa");
response.sendRedirect("#");
}
}
catch(Exception e){
System.out.println(e);
}
you are comparing two String objects rather than checking the values in the String.
just change the code to p.equals("4") and try.
String p = rs.getString(4); // This should be inside your while
int count=0;
while(rs.next()){
count++;
}
You should move your first line inside your while loop. You can't
fetch the columns of a row, until you move your cursor to that row
using res.next().
Also, since your database should ideally have only one record for a
combination of username and password. So, you can better use an
if instead of while.
And you don't really need a count variable there.
So, your code should be: -
ResultSet rs=st.executeQuery("select * from users where login='"+user+"' " +
"and password='"+pass+"'");
if (rs.next()) {
String p = rs.getString(4); // Note that using Column name is a better idea
// or rs.getInt(4) if the column type is `int`
if(p.equals("4")) { // Use equals method to compare string content
response.sendRedirect("AdminControlPanel.jsp");
} else{
out.println("aaa");
response.sendRedirect("#");
}
}
Also, note that you should compare your string using equals method. if (p == "4") will give you false result. == operator does not compare the content of the string, rather the content of the reference used in comparison.
You want
while (rs.next()) {
String val = rs.getString(4);
....
Note that iterating through a ResultSet iterates through the rows. For each row, the column indexing starts from '1'.
However it's safer to get by column name, since your SQL query doesn't specify neither the columns nor the order in which they're returned:
String val = rs.getString("COLUMN_NAME");
I see from the below that you need an integer. Check out the doc for ResultSet for more info, but:
int val = rs.getInt("COLUMN_NAME");
As an aside, I don't see you closing your ResultSet/Statement/Connection in the above. If you're not, then you'll need to!

Need help with parsing sql in java

I have the below code that splits the sql statement and give its indices for the columns.
String sql = "INSERT INTO Table1(SSN, EMPID) VALUES (?,?)";
public static List<Object[]> indices(String stmt) {
List<Object[]> list = new ArrayList<Object[]>();
String variables[] = null;
try {
variables = stmt.substring(stmt.indexOf('(')+1,
stmt.indexOf(')', stmt.indexOf('(')+1)).split("\\,");
} catch (Exception e) {}
for (int i=0; i < variables.length; ++i ) {
Object [] str = new Object [2] ;
str[0] = variables[i].trim() ;
str[1] = ((Integer)(i+1)) ;
list.add(str) ;
}
return list;
}
Result -
list[0] >>
array[0] = SSN
array[1] = 1
list [1] >>
array[0] = EMPID
array[1] = 2
Can some one point me with appropriate regular expression to split the following sql instead -
sql = "if not exists (select * from Table1 where SSN = ? and EMPID =?)
INSERT INTO Table1(SSN, EMPID) VALUES (?,?)"
I guess the output would be something like -
list[0] >>
array[0] = SSN
array[1] = 1
list [1] >>
array[0] = EMPID
array[1] = 2
list[2] >>
array[0] = SSN
array[1] = 1
list [3] >>
array[0] = EMPID
array[1] = 2
Thank You
Attempting to parse non-trivial languages like SQL using regexes or other low-level string bashing is a BAD IDEA. You end up with unreadable code and a fragile "parser" that breaks when supplied with input that is invalid or valid-but-different.
You either need to implement a proper SQL parser (or use an existing one), or change your code so that you are not parsing SQL but assembling it from something else.
I have an application depending on a framework and don't want to introduce new libraries!
That is a bad reason for not doing proper parsing. What is wrong with not using another library???
What about this one as an alternative: Zql, a SQL parser. Could make it much easier to access the 'elements' of any SQL statement.
EDIT
Easiest approach for the second SQL:
just do a sql.split("INSERT INTO") and apply your existing code to the second array entry (should be " Table1(SSN, EMPID) VALUES (?,?)"). As far as I understand your code, it should give the correct result.
Yes, I missed your point. Use a parser.
ZQL parser is great.
It can parse almost all queries except CREATE
Features:
list colums,
list tables,
FOR clause,
WHERE clause
etc

Categories