How make complex request in jdbc? [closed] - java

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed last year.
Improve this question
I want to get random name from database.
#Override
public String createName() {
String result = "empty";
String sqlSelect;
sqlSelect = "select * from names";
String sqlOrderBy = "ORDER BY RAND()";
String sqlLimit = "Limit 1";
try {
statement = connection.createStatement();
resultSet = statement.executeQuery(sqlSelect + " ; " + sqlOrderBy + " + " + sqlLimit);
//resultSet.getString("name");
System.out.println("Random name from database: " + resultSet.getString("name"));
result = resultSet.getString("name");
} catch (SQLException e) {
e.printStackTrace();
}
return result;
}
I don't know how to create request rightly. I'm a beginner in jdbc

The error in your question is the String you pass to executeQuery.
It actually translates to this select * from names ; ORDER BY RAND() + Limit 1
But it should look like this select * from names ORDER BY RAND() LIMIT 1;
So adapt this row
resultSet = statement.executeQuery(sqlSelect + " ; " + sqlOrderBy + " + " + sqlLimit);
to:
resultSet = statement.executeQuery(sqlSelect + " " + sqlOrderBy + " " + sqlLimit+";");
Additionally, you should close all resources or swap to a try with resources block
Edit: there are still a few things wrong or should be optimized
#Override
public String createName() {
String result = "empty";
String sqlSelect;
sqlSelect = "select * from names";
String sqlOrderBy = "ORDER BY RAND()";
String sqlLimit = "Limit 1";
try (
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(sqlSelect + " " + sqlOrderBy + " " + sqlLimit+";"))
{
while(restultSet.next(){
result = resultSet.getString("name");
System.out.println("Random name from database: " + result);
}
} catch (SQLException e) {
e.printStackTrace();
}
return result;
}
I switched to try with resources, so you do not have to worry about closing them since they implement the AutoClosable Interface.
Additionally you didn't mention ResultSet and Statement as variable type which makes me think that you declared it somewhere at class level. That would be a bad idea.
Edit2:
You should also use the while(ResultSet.next()) this moves the "cursor" forward and you can access the first element. If your resultset would return more rows, then it iterates over all rows and you can deal with the data in that block.

Related

How to check if there is a specific number in the database

This is my entire code:
import java.sql.*;
import java.io.*;
public class VerInformacaoPassageiro {
public static void main(String args[]) {
String dbname = "BD22";
String dbuser = "postgres";
String password = "12345";
String url = "jdbc:postgresql://localhost:5432/" + dbname;
try {
BufferedReader in;
in = new BufferedReader( new InputStreamReader( System.in ));
System.out.print("Numero de identificacao: ");
String identificacao = in.readLine();
Connection c = DriverManager.getConnection(url, dbuser, password);
c.setAutoCommit(false);
Statement stmt = c.createStatement();
String query = "SELECT nomeP, sexo, destinopretendido, dataviagem " +
"FROM passageiros " +
"WHERE nidentificacao='" + identificacao + "';";
System.out.println("QUERY: " + query);
ResultSet rs = stmt.executeQuery(query);
System.out.println( "Informacao do passageiro com numero de identificacao " + identificacao);
System.out.println( "---------------------------------------");
while ( rs.next() ) {
int nidentificacaoP = rs.getInt("nidentificacao");
String nome = rs.getString("nomeP");
String sexo = rs.getString("sexo");
String destinopretendido = rs.getString("destinopretendido");
String dataviagem = rs.getString("dataviagem");
if (nidentificacaoP == NULL)
System.out.print("Identificacao nao encontrada");
else
System.out.println( nome + " do sexo " + sexo + " para o destino " + destinopretendido + " no dia " + dataviagem );
}
rs.close();
stmt.close();
c.close();
}
catch (Exception e) {
System.err.println( e.getClass().getName()+": "+ e.getMessage() );
System.exit(0);
}
}
}
But my doubt is in this part of the code:
if (nidentificacaoP == NULL)
System.out.print("Identificacao nao encontrada");
else
System.out.println( nome + " do sexo " + sexo + " para o destino " + destinopretendido + " no dia " + dataviagem );
}
rs.close();
stmt.close();
c.close();
My goal is to find a certain ID number in a database that will give me a passenger's information. If this ID is not in the database I want to use an if to write "ID not found" but I don't know how to do this. (I left it as NULL inside the if because I didn't know what to put in it so it won't be empty, so I can submit it here on Stack Overflow). What should I write inside the if to check if the ID exists?
There are at least 3 errors/misconceptions in this code.
SQL injection
String query = "SELECT nomeP, sexo, destinopretendido, dataviagem " +
"FROM passageiros " +
"WHERE nidentificacao='" + identificacao + "';";
Imagine the user types this on the command line:
Whatever' OR 1 == 1; EXEC 'FORMAT C: /Y'; --
That would mean the query matches many records (OR 1 == 1 means it matches all of them), and it'll format your drive. This is called SQL injection; to avoid it, use PreparedStatement and NEVER put user input directly into the SQL. In general your SQL statements should be string literals.
Selecting columns vs retrieving them
String query = "SELECT nomeP, sexo, destinopretendido, dataviagem " +
....
rs.getInt("nidentificacao")
Your select statement states that you want 4 values to be returned for each matching row in the query. You then ask for the value of row 'nidentificacao' which isn't in there. The only 4 string values valid in rs.getInt, are nomeP, sexo, destinopretendido and dataviagem, because those are the only 4 columns in the query.
Misunderstanding of how 'not found' is registered
Your query returns a number of rows. while (rs.next()) loops once for each row. If nidentificacao is unique, given that you are looking for a specific value of it, your query returns either 1 row, or 0 rows.
If no row with nidentificacao at the searched-for value exists, you would get no rows. In your code, you assume you get a row, with null as value for rs.getInt("nidentificacao"); which isn't how it works.
NULL misconception
In SQL, NULL is a thing. In java, there's, at best, null (case sensitive). The various .getX() methods tend to return a placeholder value and not null for SQL NULL values. For example, if your SQL query returns NULL and you call rs.getInt(column) to retrieve it, you get 0, not null - that's because in java primitives cannot be null.
It isn't relevant here (checking for SQL NULL is not how you determine that no results are found; you determine that by realizing rs.next() will return false always - even the first time you call it) - but if it had been, that's not how its done.
Assuming identificacao is a unique identifier, the query will return either one or no rows, so you don't need to process the result set with a while, but with an if:
// Single row found
if (rs.next()) {
int nidentificacaoP = rs.getInt("nidentificacao");
String nome = rs.getString("nomeP");
String sexo = rs.getString("sexo");
String destinopretendido = rs.getString("destinopretendido");
String dataviagem = rs.getString("dataviagem");
System.out.println
(nome + " do sexo " + sexo + " para o destino " +
destinopretendido + " no dia " + dataviagem);
// No row found
} else {
System.out.print("Identificacao nao encontrada");
}
Mandatory side note:
Concatenating the condition like that is at best a bad practice and at worst leaves your application vulnerable to SQL Injection attacks if identificacao is received from user-controlled input. You should probably convert this query to a PreparedStatemet with placeholders.

SQL parameter issue Jdbc

I am taking input from user and storing in two different variables. I am binding the parameters with my sql statement. When i run the code its giving issue on concatenating part of query.
String CityA= null;
String CityB= null;
try {
CityA = readEntry(in, "Enter Origin City : ");
CityB = readEntry(in, "Enter Destination City : ");
// We treat this drop table specially to allow it to fail
// as it will the very first time we run this program
try {
String q = "SELECT f.FLNO,f.DISTANCE,TIMEDIFF(f.arrives,f.departs)
as Duration FROM FLIGHTS F"
+ " WHERE F.ORIGIN = "+CityA;
+ "AND f.DESTINATION = "+CityB;
System.out.println(q);
rset = stmt.executeQuery(q);
while (rset.next()) {
System.out.println(rset.getInt("FLNO") + ","
+ rset.getInt("Distance") + ","
+ rset.getTime("Duration"));
}
System.out.println("Done");
}
catch (SQLException e) {
// assume not there yet, so OK to continue
}
finally {
stmt.close();
}
Please find the code for query:-
Basically you missed the space between the CityA and AND
String q = "SELECT f.FLNO,f.DISTANCE,TIMEDIFF(f.arrives,f.departs) as Duration FROM FLIGHTS F"
+ " WHERE F.ORIGIN = '"+CityA+"' ";
+ "AND f.DESTINATION = '"+CityB+"'";
There is a typo in your query string - you missed the space between 'Los-Angeles' and AND.

Trying to check if values exists in MySQL

I am trying to check if the players name and the invited players name that already exists in the database, I try this:
public boolean isFriends(ProxiedPlayer inviter, ProxiedPlayer invited) {
try {
Statement sql = mySql.getConnection().createStatement();
ResultSet resultSet = sql.executeQuery("SELECT * FROM `friends` WHERE `friendinviter`='" + inviter.getName() + "'`invitedfriend`='" + invited + "';");
ProxyServer.getInstance().broadcast("1");
if(resultSet.next()) {
sql.close();
resultSet.close();
return true;
}
sql.close();
resultSet.close();
return false;
}catch (SQLException e) {
e.printStackTrace();
return false;
}
}
I tried debugging it by trying to get what it returns in the result-set but the code never came so far.
My first suggestion is you should use PreparedStatement for this portion of code.
Secondly in the line "SELECT * FROM friends WHERE friendinviter='" + inviter.getName() + "'invitedfriend='" + invited + "';" the portion "'invitedfriend='" + invited I think requires a VARCHAR to be passed as parameters but you are passing an instance of ProxiedPlayer. So the corrected code should be:
"SELECT * FROM `friends` WHERE ` friendinviter`='" + inviter.getName() + "'`invitedfriend`='" + invited.getName() + "';"
You have a syntax error in:
ResultSet resultSet = sql.executeQuery("SELECT * FROM `friends` WHERE `friendinviter`='" + inviter.getName() + "' and `invitedfriend`='" + invited + "';");
You miss the logical operator in your where clues.
You should learn about prepared statements.

LIKE Statements Not Working in Java SQL Prepared Statement

I'm working on creating a Java interface for an SQL database. I'm using prepared statements to perform the search queries, however they only work with "=" statements and not with LIKE statements.
The first sample code using "=" works successfully. The second sample, using a LIKE statement, does not work and just returns empty.
WORKS:
PreparedStatement SearchQuery = con.prepareStatement("Select * From Alumnus_A Where aFirstName = ? ORDER BY aLastName asc");
SearchQuery.setObject(1, FirstName);
ResultSet rs=SearchQuery.executeQuery();
DOESN'T WORK:
PreparedStatement SearchQuery = con.prepareStatement("Select * From Alumnus_A Where aFirstName LIKE ? ORDER BY aLastName asc");
SearchQuery.setObject(1, FirstName);
ResultSet rs=SearchQuery.executeQuery();
Any help is much appreciated, also if you could explain it to me keeping in mind I'm very new to Java and don't have a lot of programming experience yet.
The rest of my search button's code:
private void button_SearchActionPerformed(java.awt.event.ActionEvent evt) {
String FirstName = textField_FirstName.getText();
String LastName = textField_LastName.getText();
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection con=DriverManager.getConnection("jdbc:odbc:Alumni_DB");
Statement st=con.createStatement();
con.commit();
System.out.print(FirstName + " ");
PreparedStatement SearchQuery = con.prepareStatement("Select * From Alumnus_A Where aFirstName LIKE ? ORDER BY aLastName asc");
SearchQuery.setString(1, FirstName);
ResultSet rs=SearchQuery.executeQuery();
String aUID="",aFName="",aLName="",aMInitial="",aHomePhone="",aCellPhone="";
while(rs.next())
{
aUID=rs.getString(1);
aFName=rs.getString(2);
aLName=rs.getString(3);
aMInitial=rs.getString(4);
aHomePhone=rs.getString(5);
aCellPhone=rs.getString(6);
System.out.println("UID " + aUID + " First Name " + aFName + " Last Name " + aLName + " Middle Initial " + aMInitial + " Home Phone " + aHomePhone
+ " Cell Phone " + aCellPhone);
}
}
catch(Exception e)
{
System.out.println(e);
}
}
Note: Anything with the prefix 'a' is referring to a database column

java.lang.NullPointerException - ResultSet

I am getting the following error:
java.lang.NullPointerException
at oracle.jdbc.driver.ScrollableResultSet.cacheRowAt(ScrollableResultSet.java:2086)
at oracle.jdbc.driver.ScrollableResultSet.isValidRow(ScrollableResultSet.java:2060)
at oracle.jdbc.driver.ScrollableResultSet.next(ScrollableResultSet.java:347)
at website.web.InboxReader.getkeywordImportance(InboxReader.java:832)
at website.web.InboxReader.main(InboxReader.java:54)
There are 53 rows in Mail table and 1 row in keyword table. On debugging, as soon as the line is executed kstmt.executeUpdate("UPDATE KEYWORD SET IMPORTANCE = IMPORTANCE + 1.0 WHERE SKEYWORD = '" + s2 + "'"); it goes again to keyword set.next() and throws the exception.
Here is the code:
Connection connection = connectToDatabase();
Statement mstmt = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
String s1,s2;
ResultSet mailset = mstmt.executeQuery("SELECT * from MAIL");
System.out.println("hello in getImportance beg");
//mailset.beforeFirst();
while(mailset.next())
{
System.out.println("hello in first while");
Statement kstmt = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
ResultSet keywordset = kstmt.executeQuery("SELECT * FROM KEYWORD");
while(keywordset.next())
{
s1=mailset.getString("SUBJECT");
System.out.println("Subject: "+s1);
s2=keywordset.getString("SKEYWORD");
System.out.println("Keyword: "+s2);
if(s1.contains(s2))
{
System.out.println("hello in if");
kstmt.executeUpdate("UPDATE KEYWORD SET IMPORTANCE = IMPORTANCE + 1.0 WHERE SKEYWORD = '" + s2 + "'");
}
}
keywordset.close();
}
mailset.close();
connection.close();
Thanks!
if you take a look at this line which seems to be problematic:
kstmt.executeUpdate("UPDATE KEYWORD SET IMPORTANCE ='" + (keywordset.getFloat("IMPORTANCE") + 1.0) + "'");
You should double check the call
keywordset.getFloat("IMPORTANCE")
This mostlikely due to the fact the the column Importance is empty for the record or that the column might not exist. Just to debug you try with
keywordset.getFloat(0);
or which ever id of a column you know exist to see if the call works.
Have you tried removing the COMMIT statement ? Because usually unless you specify otherwise the data is automatically committed so there is no need to call a commit after your statement and if you have specified the auto_commit to false then to commit you should do con.commit() and not call it through an update statement
Please see the documentation here
http://download.oracle.com/javase/tutorial/jdbc/basics/retrieving.html
No need to call beforeFirst as you seem to expect next to behave.
public static void viewTable(Connection con) throws SQLException {
Statement stmt = null;
String query = "select COF_NAME, SUP_ID, PRICE, SALES, TOTAL from " + dbName + ".COFFEES";
try {
stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
String coffeeName = rs.getString("COF_NAME");
int supplierID = rs.getInt("SUP_ID");
float price = rs.getFloat("PRICE");
int sales = rs.getInt("SALES");
int total = rs.getInt("TOTAL");
System.out.println(coffeeName + "\t" + supplierID + "\t" + price + "\t" + sales + "\t" + total);
}
} catch (SQLException e ) {
JDBCTutorialUtilities.printSQLException(e);
} finally {
if (stmt != null) { stmt.close(); }
}
}
Have you tried running it without keywordset.beforeFirst() and mailset.beforeFirst() ? That is not required, and it might be creating an issue in ResultSet.
kstmt.executeUpdate("UPDATE KEYWORD SET IMPORTANCE = IMPORTANCE + 1.0 WHERE SKEYWORD = '" + s2 + "'");
When this line execute in your code your keywordset ResultSet object will change because all execute methods will cause effect on ResultSet.
All execution methods in the Statement interface implicitly close a statment's current ResultSet object if an open one exists.
What you have to do is create a separate object of statement for running this query so that keywordset ResultSet won't get affected ... ...:)

Categories