Can I use setMaxRows() with try-with-resouces? - java

I am attempting to write a method that selects 2 entries into an employee database and removes them (Based on a salary field), I am currently using a counter to accomplish this, however I tried using setMaxRows() so my result set would only have two entries, thus eliminating the need for the counter. I am using try-with-resources to create my statement and that seems to be causing an issue.
public void downSize(Connection con) {
String sql = "SELECT * FROM " + schemaName + "."+tableName+" WHERE EMPLOYEE_SALARY>200000";
try (
PreparedStatement statement = con.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
ResultSet rs = statement.executeQuery();
)
{
int counter = 0;
System.out.println("Now pruning workforce...");
while(rs.next() && counter<2) {
String name = rs.getString("EMPLOYEE_NAME");
rs.deleteRow();
counter++;
System.out.println(name+" was laid off.");
}
} catch(Exception e) {
e.printStackTrace();
System.out.print("Sql exception happened");
}
}

Related

How to hold MySQL query result in an int variable if possible

I want to know whether a table exist or not before creating another one is there any way of holding result in a variable after execution of command, i am using this code but it keeps giving only true even if table doesn't exists.
public static boolean checkBefore(){
boolean r = false;
try{
query = "SELECT COUNT(*)FROM information_schema.tables WHERE table_schema = 'sms' AND table_name = 'auth';";
con = connectsms();
st = con.createStatement();
ResultSet rs = st.executeQuery(query);
r = rs.next();
}catch(SQLException e){
JOptionPane.showMessageDialog(errorMsg,"Exeption Fount: "+e,"Opps! Exception Found in checkBefore()",JOptionPane.ERROR_MESSAGE);
}
System.out.println(r);
return r;
}
Every JDBC guide will show you that after executing a query, you need to call next() to advance to the next/first row, then call getter methods to retrieve the column values of that row.
Queries with aggregating functions (COUNT, MIN, MAX, etc) without a GROUP BY clause will always return exactly one row, so for those kinds of queries, you don't need to check the return value from next(). For pretty much all other queries, you do.
When calling JDBC methods that return resources, you should use try-with-resources to make sure those resource are cleaned up correctly.
Query string does not need to end with a ; semi-colon.
All that means that your code should be:
public static boolean checkBefore() {
String sql = "SELECT COUNT(*)" +
" FROM information_schema.tables" +
" WHERE table_schema = 'sms'" +
" AND table_name = 'auth'";
try ( Connection con = connectsms();
Statement st = con.createStatement();
ResultSet rs = st.executeQuery(sql);
) {
rs.next(); // exactly one row returned, so next() always returns true here
int count = rs.getInt(1); // get value from first column
System.out.println("count = " + count);
return (count != 0);
} catch (SQLException e) {
JOptionPane.showMessageDialog(errorMsg, "Exeption Fount: " + e,
"Opps! Exception Found in checkBefore()",
JOptionPane.ERROR_MESSAGE);
return 0;
}
}
Change r = rs.next(); to rs.next(); and then add r = rs.getInt(1) > 0; and it will work.
This is the query that worked for me:
SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'databse_name';
and the code that i am using and is working correct:
public static boolean checkBefore(){
boolean result = false;
try{
query = "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'sms'";
con = connectsms();
st = con.createStatement();
ResultSet rs = st.executeQuery(query);
result = rs.next();
System.out.println();
}catch(SQLException e){
JOptionPane.showMessageDialog(errorMsg,"Exeption Fount: "+e,"Opps! Exception Found in checkBefor()",JOptionPane.ERROR_MESSAGE);
}
try{
con.close();
}
catch(SQLException e){JOptionPane.showMessageDialog(errorMsg,"Exeption Fount: "+e,"unable to close connection",JOptionPane.ERROR_MESSAGE); }
System.out.println(result);
return result;
}

Pull string from sql to java

I am trying to pull a first name and last name from a table in my SQL database. The queries work fine in SQL without the "as First" part and I know the db connection is fine since it works in every other part of the code.
The error I receive is that table "First" does not exist, but it should be looking at firstName and lastName for the table names, not First and Last.
Its inside of a for loop with "i", but those values are correct, playerid = i exists.
try {
String query2 = " SELECT firstName as First from player "
+ "WHERE playerid = ?";
PreparedStatement st2 = db.conn.prepareStatement(query);
st2.setInt(1, i);
ResultSet rs2 = st2.executeQuery();
if (rs2.next()) {
setFirstName(rs2.getString("First"));
}
String query3 = " SELECT lastName as Last from player "
+ "WHERE playerid = ?";
PreparedStatement st3 = db.conn.prepareStatement(query);
st3.setInt(1, i);
ResultSet rs3 = st3.executeQuery();
if (rs3.next()) {
setLastName(rs3.getString("Last"));
}
}
catch (SQLException e) {
e.printStackTrace();
}
Change your code into something like this:
PreparedStatement ps = null;
try {
ps = db.conn.prepareStatement("SELECT firstName, lastName from player "
+ "WHERE playerid = ?");
for (int i = 0; i < MAX_PLAYERS /*<- or what is the loop condition?*/; i++) {
ps.setInt(1, i);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
// should these methods really be called within a loop?
setFirstName(rs.getString("firstName"));
setLastName(rs.getString("lastName"));
}
rs.close();
}
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
if (ps != null) {
ps.close();
}
}
Some considerations:
When you're using a PreparedStatement within a loop, you should create the statement once, outside of the loop and then only re-assign the bind variable(s) during each iteration.
You should minimize the number of queries you run against the DB; in your case you should select both the first and last name column in a single query.
It is important to close the resources you open up (the PreparedStatement in this case). My example shows how this is usually done (in the finally block) pre Java 7. Use the try-with-resources statement if you're using a newer Java version.

JDBC ResultSet is giving only one row although there are many rows in table?

I am having many rows in table and I ran the same query on my database which is MySql but java ResultSet is only giving the first row of the table. Here is my code.
public ArrayList<String> getAllAlbumsName(Integer uid) {
ArrayList<String>allAlbumsName = new ArrayList<String>();
try {
String qstring = "SELECT albumname FROM picvik_picture_album WHERE " +
"uid = '" + uid + "';";
System.out.println(qstring);
connection = com.picvik.util.MySqlConnection.getInstance().getConnection();
ptmt = connection.prepareStatement(qstring);
resultSet = ptmt.executeQuery();
if(resultSet.next()) {
System.out.println(resultSet.getString("albumname"));
allAlbumsName.add(resultSet.getString("albumname"));
}
resultSet.close();
ptmt.close();
connection.close();
} catch (Exception e) {
e.printStackTrace();
}
return allAlbumsName;
}
if(resultSet.next()) {
System.out.println(resultSet.getString("albumname"));
allAlbumsName.add(resultSet.getString("albumname"));
}
If you would like to get all rows, it should be:
while(resultSet.next()) {
System.out.println(resultSet.getString("albumname"));
allAlbumsName.add(resultSet.getString("albumname"));
}
The while statement continually executes a block of statements while a particular condition is true
Note: As #BalusC commented, your code would introduce SQL Injection attack, it is better to use ptmt.set... Instead of constructing SQL String manually.
try while(resultSet.next()) {
instead of if (resultSet.next()) {
Change if (resultSet.next()) { to while (resultSet.next()) {

compare integer text field value with mysql data in java

I want to check whether the newly entered data is already in the table
code:
txtNo = new JTextField();
{
try {
Class.forName("com.mysql.jdbc.Driver");
String srcurl1 = "jdbc:mysql://localhost:3306/DB_name";
Connection con = DriverManager.getConnection(srcurl1,"root","paswrd");
Statement stmt1 = con.createStatement();
ResultSet rs1 = stmt1.executeQuery("select No from bank where No='"+txtNo.getText()+"' ");
int ch =rs1.getInt("No");
int ch4= Integer.parseInt(txtNo.getText());
if(ch==ch4) // input 58 == 58
System.out.println("already exits");
}
catch(Exception e)
{
System.out.println("Exception:"+e);
}
}
Error :
Exception:java.sql.SQLException: Illegal operation on empty result set.
You need to check if the result set has elements or not:
while(rs1.next())
{
int ch = rs1.getInt("No");
// ...
}
You get this exception when the select statement returns an empty set. Add a try/catch block which acts upon the knowledge that the data is not already in the table in the catch block.
You need to check the ResultSet first to check to see that it contains rows:
if (rs1.next()) {
int ch =rs1.getInt("No");
...
}
The easiest way to check whether a particular record exists in the database might be just as follows:
Select 1 from bank where No = [your_supplied_value]
This query would return 1 if it finds a row in your database with the supplied data or return an empty resultset. So, all you need to check is whether ANY value is returned in the resultset or whether it is emtpy.
Here's a sample code to get you started:
txtNo = new JTextField();
{
try {
String compareText = txtNo.getText().trim();
if(compareText.length() > 0){
Class.forName("com.mysql.jdbc.Driver");
String srcurl1 = "jdbc:mysql://localhost:3306/DB_name";
Connection con = DriverManager.getConnection(srcurl1,"root","paswrd");
Statement stmt1 = con.createStatement();
ResultSet rs1 = stmt1.executeQuery("select 1 from bank where No='"+txtNo.getText()+"' ");
boolean isPresent = rs1.next();
if(isPresent){
System.out.println("Already exists!!");
}
}
}
catch(Exception e)
{
System.out.println("Exception:"+e);
}
}
I hope this is not your final code, because there're several problems with it:
You're not managing your resources properly. Once you're done querying your database, you should consider closing your resultset, statement and connection objects.
Note that I checked whether the text in the JTextField is empty or not. This is a good way of preventing a call to the database when you know that the text field had no value in it.
I would suggest using a PreparedStatement rather than a Statement for querying to your database.
A ResultSet is initially positioned before the first row. So you need to call next() to move it to the next row (and check that it returns true) before you call one of the getXXX() methods.
JTextField input = new JTextField();
ArrayList < Integer > list = new ArrayList < Integer > ();
int integerv = Integer.parseInt(input.getText());
try {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/DB_name", "root", "yourpassword");
Statement stm = con.createStatement();
ResultSet rs = stm.executeQuery("select column_name from table_name");
while (rs.next()) {
list.add(rs.getInt(1));
}
for (int a = 0; a < list.Size(); a++) {
if (a.get(a) == integerv) {
System.out.println("Match found");
break;
} else {
System.out.println("Match not found");
break;
}
}
} catch (Exception e) {
System.out.println("Error :" + e.getMessage());
}

Queries returning multiple result sets

I have a MSSQL database and am running the following query:
select * from projects; select * from user
The above query returns two result sets at once, and I cannot fire both queries separately. How can I handle both the result set at once in a Java class?
Correct code to process multiple ResultSets returned by a JDBC statement:
PreparedStatement stmt = ...;
boolean isResultSet = stmt.execute();
int count = 0;
while(true) {
if(isResultSet) {
rs = stmt.getResultSet();
while(rs.next()) {
processEachRow(rs);
}
rs.close();
} else {
if(stmt.getUpdateCount() == -1) {
break;
}
log.info("Result {} is just a count: {}", count, stmt.getUpdateCount());
}
count ++;
isResultSet = stmt.getMoreResults();
}
Important bits:
getMoreResults() and execute() return false to indicate that the result of the statement is just a number and not a ResultSet.
You need to check stmt.getUpdateCount() == -1 to know if there are more results.
Make sure you either close the result sets or use stmt.getMoreResults(Statement.CLOSE_CURRENT_RESULT)
You can use Statement.execute(), getResultSet();
PreparedStatement stmt = ... prepare your statement result
boolean hasResults = stmt.execute();
while (hasResults) {
ResultSet rs = stmt.getResultSet();
... your code parsing the results ...
hasResults = stmt.getMoreResults();
}
Yes, You can. See this MSDN article
https://msdn.microsoft.com/en-us/library/ms378758(v=sql.110).aspx
public static void executeStatement(Connection con) {
try {
String SQL = "SELECT TOP 10 * FROM Person.Contact; " +
"SELECT TOP 20 * FROM Person.Contact";
Statement stmt = con.createStatement();
boolean results = stmt.execute(SQL);
int rsCount = 0;
//Loop through the available result sets.
do {
if(results) {
ResultSet rs = stmt.getResultSet();
rsCount++;
//Show data from the result set.
System.out.println("RESULT SET #" + rsCount);
while (rs.next()) {
System.out.println(rs.getString("LastName") + ", " + rs.getString("FirstName"));
}
rs.close();
}
System.out.println();
results = stmt.getMoreResults();
} while(results);
stmt.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
I've tested that and it works fine.
Before use java, you need look at the RESULT SETS clause.
MSSQL has this feature that can help you with your java code, in a more practical way.
This example will exec two queries:
EXEC('SELECT id_person, name, age FROM dbo.PERSON; SELECT id_url, url FROM dbo.URL;')
WITH RESULT SETS
(
(
id_person BIGINT,
name VARCHAR(255),
age TINYINT
),
(
id_url BIGINT,
url VARCHAR(2000)
)
);
You can use stored procedures with RESULT SETS as well.
More about: https://technet.microsoft.com/en-us/library/ms188332(v=sql.110).aspx
public static void executeProcedure(Connection con) {
try {
CallableStatement stmt = con.prepareCall(...);
..... //Set call parameters, if you have IN,OUT, or IN/OUT parameters
boolean results = stmt.execute();
int rsCount = 0;
//Loop through the available result sets.
while (results) {
ResultSet rs = stmt.getResultSet();
//Retrieve data from the result set.
while (rs.next()) {
....// using rs.getxxx() method to retrieve data
}
rs.close();
//Check for next result set
results = stmt.getMoreResults();
}
stmt.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
The UNION ALL query allows you to combine the result sets of 2 or more "select" queries. It returns all rows (even if the row exists in more than one of the "select" statements).
Each SQL statement within the UNION ALL query must have the same number of fields in the result sets with similar data types.........
select * from projects
UNION ALL
select * from user
The answer: it is NOT possible. The only way: Run them as separate queries.

Categories