resultSet is null, how ever mysql query is correct - java

I have problem with my java code (Resultset is null). It was working on localhost until I have tried remote Mysql scalegrid hosting . The most interesting is that, if I use Mysql Workbench query works fine and returns all rows. What I am doing wrongly.
I have tried to commit my table manually;
Query (SELECT * FROM ShopDatabase.DATA) works fine;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.sql.*;
public class Main {
public static void main(String[] args) throws ParserConfigurationException, IOException, SQLException, ClassNotFoundException {
String userName = "App";
String password = "AppShopData+2";
String connectionUrl = "jdbc:mysql://SG-ShopDatabase-821-master.servers.mongodirector.com:3306/ShopDatabase";
try(Connection connection = DriverManager.getConnection(connectionUrl, userName, password)){
System.out.println("Connection established");
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("SELECT * FROM ShopDatabase.DATA where product_name = 'Хлеб';");
while(resultSet.next()){
System.out.println(resultSet.getInt("id"));
System.out.println("----------------");
}
}
}
}

Remove ; at the end of the query:
ResultSet resultSet = statement.executeQuery(
"SELECT * FROM ShopDatabase.DATA where product_name = 'Хлеб'");

Given the correct MySQL connection and that there is indeed a column value 'Xлеб' there:
Remove ";" at the end of the query and check
If the above won't work, eliminate possible internationalization issues (whatever they can be): Store "Bread" instead of Xлеб and see whether you have results (Xлеб is bread in Russian). Of course you'll need to adjust the query correspondingly

Related

SQL query can't execute when it contains selected autoincrement row

I have in one java class a method which SELECT one column from a table from my database, and that column is an INT type in the database, and then I selected items from that column, put in a List<Long> and method returns this List. Here is the method:
public List<Long> vratiSveSifreRacuna() throws SQLException {
String sqlVratiSifruRacuna = "SELECT RacunID FROM racun";
Statement stat = konekcija.createStatement();
ResultSet rs = stat.executeQuery(sqlVratiSifruRacuna);
Long racunID = 0L;
List<Long> sifre = new ArrayList<>();
while (rs.next()){
//racunID = rs.getLong("RacunID");
sifre.add(new Long(rs.getInt("RacunID")));
}
return sifre;
}
The problem is, when I start debuging line by line, on this line:
ResultSet rs = stat.executeQuery(sqlVratiSifruRacuna);
it crashes, it jumps on exception. It cannot execute this query and I don't know why, because similar queries it execute well. Do you know what could be the problem? Is the problem maybe because the column I want to select is autoincrement and primary key? I don't know...
Your public (assuming static) method needs the connection object passed into it as an argument as it is not available in the local scope:
public static List<Long> vratiSveSifreRacuna(Connection konekcija) throws SQLException {
String sqlVratiSifruRacuna = "SELECT RacunID FROM racun";
Statement stat = konekcija.createStatement();
ResultSet rs = stat.executeQuery(sqlVratiSifruRacuna);
Otherwise include connection inside local context:
public static List<Long> vratiSveSifreRacuna(String url, String username, String password) throws SQLException {
Connection konekcija = DriverManager.getConnection(url, username, password);
String sqlVratiSifruRacuna = "SELECT RacunID FROM racun";
Statement stat = konekcija.createStatement();
ResultSet rs = stat.executeQuery(sqlVratiSifruRacuna);
I solved the problem finally so I wanted to share the solution. The problem was actually stupid, I accidentally put the code line which makes connection with database below the line where I called this method. So there where the method was called, sql query was actually empty, so it alerts error nullPointerException.

can't retrieve data from database

Problem was:
Can't get just inserted data from the table. From the error message it looks like it doesn't see the first column. I know the column is there and data was inserted. I checked database. I checked if column Number has some hidden space in name. No it doesn't.
Tried:
Debugged every line and everything was good together with inserting data to database.
Found the issue is almost at the end of the code:
rs1.next();
String s1 = rs1.getString(1);
I tried to write
rs1.first();
String s1 = rs1.getString(1);
or
rs1.first();
String s1 = rs1.getString("Number");
Below I posted my final code that is working correctly and I am able to insert data to the table and display on the browser.
package mypackage;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Collections;
import java.util.LinkedList;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
#Path("/query")
public class CList {
private LinkedList<SMember> contacts;
public CList() {
contacts = new LinkedList();
}
#GET
#Path("/{CList}")
public Response addCLocation(#QueryParam("employeeId") String eId) throws SQLException{
String dataSourceName = "DBname";
String dbURL = "jdbc:mysql://localhost:3306/" + dataSourceName;
String result = "";
Connection con = null;
PreparedStatement ps0 = null, ps = null;
ResultSet rs = null, rs1 = null;
String id = eId;
try {
try{
//Database Connector Driver
Class.forName("com.mysql.jdbc.Driver");
//Connection variables: dbPath, userName, password
con = (Connection)
DriverManager.getConnection(dbURL,"someusername","somepassword");
System.out.println("We are connected to database");
//SQL Statement to Execute
System.out.print(id);
s = con.prepareStatement("SELECT 1 FROM CList WHERE Number=?");
s.setString(1, eId);
rs = s.executeQuery();
//Parse SQL Response
if(!rs.next()) {
SMember sm = new SMember();
ps = (PreparedStatement) con.prepareStatement("INSERT
INTO Contact_List (Number, First_Name, Last_Name, Phone_Number) " +
"VALUES (?,?,?,?)");
ps.setString(1,sm.getEmployeeID());
ps.setString(2,sm.getFirstName());
ps.setString(3,sm.getLastName());
ps.setString(4,sm.getPhone());
ps.executeUpdate();
ps = con.prepareStatement("SELECT Number, First_Name,
Last_Name, Phone_Number FROM CList
WHERE Number=" + eId);
rs1 = ps.executeQuery();
while(rs1.next()){
result = "[Added contact to contact list.
Number: " + rs1.getString(1) +
"][First_Name: " + rs1.getString(2) +
"][Last_name: " + rs1.getString(3) +
"][Phone_Number: " + rs1.getString(4) +
"]\n";
}
}
else {
result = "[Contact is already on the list]";
}
}
catch(Exception e) {
System.out.println("Can not connect to database");
e.printStackTrace();
}
finally {
//Close Database Connection
ps0.close();
ps.close();
con.close();
}
}
catch(Exception e) {
System.out.println(e);
}
//Return the Result to Browser
return Response.status(1000).entity(result).build();
}
Table
1234 number is unique and it is a number I want to get.
You see number should be unique. So far I am taking data from the SMember class and it always insers the same data. Purpose of my question is just to ge the information I inserted few seconds ago.
Also, there is SMember class that I didn't post here and in its constructor I initialize number, first name, last name, and phone number. Testing purpose.
I made all recommended changes but problem remains the same.
There is several issues here.
The solution to your question is that you do not let the database generate keys, that is why you cannot ask for the generated keys later.
Look at this line of your code:
ps = (PreparedStatement) con.prepareStatement("INSERT INTO CList (Number, First_Name, Last_Name, Phone_Number) VALUES ('"+sm.getEmployeeID()+"', '"+sm.getFirstName()+"', '"+sm.getLastName()+"', '"+sm.getPhone()+"')", Statement.RETURN_GENERATED_KEYS);
You later want to retrieve the Number column's value as a generated key. You however do pass a value for that column, namely the return value of sm.getEmployeeID(). If you pass a value, it will not get generated (assuming that this column is defined in database as being auto incremented.
Fixing this however, will not solve everything as your code has quite a lot of issues. Let me list the ones I can directly spot:
You initialize your variable sm by creating a new object. But you will still not have values for employee id, first name, last name or phone number as you nowhere set those values to sm (or do you do that in the default constructor?).
You are trying to use a prepared statement, this is good, but you are actually not doing that, this is very bad as it openes the ground for SQL injection. Instead of creating the query string like you are doing, you should use a fixed string like e.g INSERT INTO CList (Number, First_Name, Last_Name,Phone_Number) VALUES (?,?,?,?) and then set the values on the statement before executing it. That way nobody can mess with your database through that statement (read up on SQL injection, just google it to see the issue you would introduce).
Your employee id seems to be the eId parameter of your method. You should use that also in your select statement to see if it is already in your database (use a prepared statement here also) and in your insert statement later when the id is not already in the database.
If you are checking for a specific id, then insert that specific id, it is quite useless to retrieve some generated id. You already have defined your unique identifier. Use that one!
Edit: As your code is kind of a mess, I have cleaned this stuff a bit and fixed the issues that I could directly find. Check if this is helping you:
public Response addCLocation(String eId) throws SQLException {
String dataSourceName = "DBname";
String dbURL = "jdbc:mysql://localhost:3306/" + dataSourceName;
String result = "";
Connection con = null;
Statement s = null;
PreparedStatement ps = null;
ResultSet rs = null, rs1 = null;
String id = eId;
try {
try {
// Database Connector Driver
Class.forName("com.mysql.jdbc.Driver");
// Connection variables: dbPath, userName, password
con = DriverManager.getConnection(dbURL, "someusername", "somepassword");
System.out.println("We are connected to database");
s = con.createStatement();
// SQL Statement to Execute
System.out.print(id);
PreparedStatement alreadyThere = con.prepareStatement("SELECT 1 FROM CList WHERE Number = ?");
alreadyThere.setString(1, eId);
System.out.println("0");
// Parse SQL Response
int i = 0;
if (rs.next() == false) {
SMember sm = new SMember();
ps = con
.prepareStatement("INSERT INTO Contact_List (Number, First_Name, Last_Name, Phone_Number) VALUES (?,?,?,?)");
ps.setString(1, sm.getEmployeeID());
ps.setString(2, sm.getFirstName());
ps.setString(3, sm.getLastName());
ps.setString(4, sm.getPhone());
ps.executeUpdate();
}
else {
result = "[Contact is already on the list]";
}
}
catch (Exception e) {
System.out.println("Can not connect to database");
e.printStackTrace();
}
finally {
// Close Database Connection
s.close();
ps.close();
con.close();
}
}
catch (Exception e) {
System.out.println(e);
}
// Return the Result to Browser
return Response.status(200).entity(result).build();
}
You are getting this error because your first query is wrong it is returning an empty resultset.
Firstly,
rs = s.executeQuery("SELECT 1 FROM CList WHERE Number='id'");
the above line in your code is not correct it should be like this:
**rs = s.executeQuery("SELECT 1 FROM CList WHERE Number="+id);**
then the correct query will be fired to database.
Secondly,there is problem in following code
if(rs.next() == false) {
SMember sm = new SMember();
ps = (PreparedStatement) con.prepareStatement("INSERT
INTO CList (Number, First_Name, Last_Name,
Phone_Number) VALUES ('"+sm.getEmployeeID()+"',
'"+sm.getFirstName()+"', '"+sm.getLastName()+"',
'"+sm.getPhone()+"')",
Statement.RETURN_GENERATED_KEYS);
ps.executeUpdate();
In the above code you should initialize the SMember, object currently in query they are going as null also the when you are using PreparedStatement you should use the query like this:
**ps = (PreparedStatement) con.prepareStatement("INSERT INTO CList (Number, First_Name, Last_Name,Phone_Number) VALUES (?,?,?,?)",Statement.RETURN_GENERATED_KEYS);
ps.setString(1,sm.getEmployeeID());
ps.setString(2,sm.getFirstName());
ps.setString(3,sm.getLastName());
ps.setString(4,sm.getPhoneNumber());**
The Query statement maybe an issue "SELECT 1 FROM CList WHERE Number='id'",In select statement your id is taken as a String.we need to replace with value.
-->Try like this {"SELECT 1 FROM CList WHERE Number="+id},
-->One more thing "select 1 from table name" will print 1 for no of rows avail for your condition.
So my suggestion is
{"SELECT * FROM CList WHERE Number="+id}
try This!!
"SELECT 1 FROM CList WHERE Number='id'"
It looks like you're trying to actually select records where the Number value is 'id'. That may be causing the error when you try to do the "rs.next()" command on an empty result set. Are you instead trying to do something like
"SELECT 1 FROM CList WHERE Number=' " . id . "'"? Where "id" is a variable?

PreparedStatement doesn't change anything

I wrote this code after an example i found on the net but it doesn't work, could you please tell me what is possibly wrong with it. It seems to do something and prints out the result but nothing changes.
package com.company.Start;
import java.sql.*;
public class PreparedStmt
{
public static void main(String[] args) throws Exception
{
Class.forName("oracle.jdbc.OracleDriver");
Connection con = DriverManager.getConnection("jdbc:oracle:thin:#PC:1521/XE","ACCOUNT", "password");
PreparedStatement updateDB = con.prepareStatement("UPDATE Customers SET lname=? WHERE name=?");
updateDB.setString(1, "Meier");
updateDB.setString(2, "Peter");
updateDB.execute();
Statement smt = con.createStatement();
String query = "SELECT * FROM customers";
ResultSet rs = smt.executeQuery(query);
System.out.println("NAME LNAME ADRESS");
while (rs.next()) {
String name = rs.getString("name");
String lname = rs.getString("lname");
System.out.println(name + " " + lname);
}
}
}
Try "... WHERE name LIKE ?" and for value put "%Peter%"
I guess the name is not matched, because there is a blank or something.
Mind that the above will also change entries like "Peter-Alexander" or "Hans-Peter".
So this is just a prove that it is the value not being matched exactly.
Try using updateDB.executeUpdate() instead of updateDB.execute() . Strangely execute does not work for data updates in most of the cases.
Your code seems fine.
What is the value (int) returned by updateDB.executeUpdate();?
What does a DB utility (like SQLFront) produce given the same statement?
Try con.setAutoCommit(true); and updateDB.close();

Eclipse Compiler error saying connection variable cannot be resolved to a type

this is a Java Code i wrote in Eclipse to retrieve information from a MySQL Database.. But the Compiler is giving an error saying conn cannot be resolved to a type.. can anyone pls tel me what i may be doin wrng??
import java.sql.*;
public class plh {
static Connection conn=null;
static Statement s=null;
public static void main(String[] args){
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/wonkashop","root", "");
String st= new String("select * from users;");
s= new conn.createStatement(st);//ERROR.. why??
}
catch (Exception e) {
System.out.println("Unable to connect to Database");
}
}
}
Here in the line
s= new conn.createStatement(st);//ERROR.. why??
there is no need for new keyword
like
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(credentials);
stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(st);
I had the same issue, and surfing by Internet triying to get a solution without successful I put these imports and it works for me.
import java.sql.*;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
I hope this can help more people.
Remove the new keyword from your line of code. You need to get the Statement as :
s= conn.createStatement(); // createStatement doesn't take a String argument
DriverManager.getConnection() already returns a Connection object , which you have referenced by the identifier conn , hence use it to get the Statement .
If you want to pass the sql query string , use a PreparedStatement instead of a Statement.
That is Connection#prepareStatement(sql).
Statement :
final String st= "select * from users;";
Statement s = conn.createStatement();
ResultSet rs = stmt.executeQuery(st);
PreparedStatement:
final String st= "select * from users;";
PreparedStatement preparedStatement = conn.prepareStatement(st);
ResultSet rs = preparedStatement.executeQuery();
change this line
s= new conn.createStatement(st);//ERROR.. why??
to
s= conn.createStatement();
Connection#createStatement
Returns a new default Statement object.
Just conn.createStatement();. Don't put new here, because you're not instantiating a class.
You should only write new before the name of a class, because it creates an object of that class. But here, conn is not the name of a class - it's just the name of a variable that references an existing object of some class.
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/wonkashop", "root", "");
st= "select * from users";
s = conn.createStatement();// fixed
ResultSet rs = s.executeQuery(st);
while(rs.next()){
//Retrieve by column name
int id = rs.getInt("id");
String name = rs.getInt("name");
}
}

How to check if a table or a column exists in a database?

I am trying to make simple java code that will check if a table and/or a column exists in a MySQL DB. Should I use Java code to do the checking or make a SQL query string and execute that to do the checking ?
EDIT-
# aleroot -
I tried using your code as shown below. I don't see any tables or columns when I run the code below. I only see this-
Driver Loaded.
Got Connection.
My DB has got a lot of DB's, tables and columns. I dont know why this program works properly.
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class Tester {
static Connection conn;
static Statement st;
public static void main(String[] args) throws Exception {
try {
// Step 1: Load the JDBC driver.
System.out.println("Driver Loaded.");
// Step 2: Establish the connection to the database.
String url = "jdbc:mysql://localhost:3306/";
conn = DriverManager.getConnection(url, "cowboy", "123456");
System.out.println("Got Connection.");
st = conn.createStatement();
} catch (Exception e) {
System.err.println("Got an exception! ");
e.printStackTrace();
System.exit(0);
}
DatabaseMetaData md2 = conn.getMetaData();
ResultSet rsTables = md2.getColumns(null, null, "customers", "name");
if (rsTables.next()) {
System.out.println("Exists !");
}
}
}
To check if a table exist you can use DatabaseMetaData in this way :
DatabaseMetaData md = connection.getMetaData();
ResultSet rs = md.getTables(null, null, "table_name", null);
if (rs.next()) {
//Table Exist
}
And to check if a column exist you can use it in a similar way :
DatabaseMetaData md = connection.getMetaData();
ResultSet rs = md.getColumns(null, null, "table_name", "column_name");
if (rs.next()) {
//Column in table exist
}
SELECT * FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA='table_schema'
AND TABLE_NAME='table_name'
AND COLUMN_NAME='column_name'
If this sql returns nothing - column not exists. You can execute this query on java side, but this depends what you use (JPA, JDBC, JDBCTemplate).
In Apache Derby (SQL)
E.g. check if column exists:
SELECT ss.SCHEMANAME, st.TABLENAME, sc.COLUMNNAME FROM SYS.SYSSCHEMAS ss
INNER JOIN SYS.SYSTABLES st ON st.SCHEMAID = ss.SCHEMAID AND st.TABLENAME = <YOUR TABLE NAME>
INNER JOIN SYS.SYSCOLUMNS sc ON sc.REFERENCEID = st.TABLEID AND sc.COLUMNNAME = <YOUR COLUMN NAME>
WHERE ss.SCHEMANAME = <YOUR SCHEMA>
Knowing that you can practically select a column from a table using the following SQL statement (in MySQL):
show columns from TABLE_NAME where field = 'FIELD_NAME';
You could do something like:
...
PreparedStatement preparedStatement =
connection.prepareStatement(
"show columns from [TABLE_NAME] where field = ?");
preparedStatement.setString(1, columName);
ResultSet resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
System.out.println("column exists!");
} else {
System.out.println("column doesn't exists!");
}
...

Categories

Resources