Sqlite Query Issue - java

Alright, so I'm trying to store data in Sqlite. So I'm trying to store the id of the user with the a "line". Yet, it seems that the where clause is failing me.
String query = "SELECT * FROM Users WHERE username='Fellixombc";
ResultSet result = this.sqlStatement.executeQuery(query);
int userId = 0;
while(result.next()) {
System.out.println("TRUE");
userId = result.getInt("id");
System.out.println(result.getString("username"));
}
And true is not printing. Yet, if I remove the WHERE clause from the query, it will print out all of the usernames/id's fine, and of course "TRUE".
Am I missing something with Sqlite and it's syntax?
edit: Just to clarify there is a user in the Users column with the id of 1 and with the username Fellixombc
edit: So I took your guy's suggestion and tried prepare statement, heres my code now:
PreparedStatement sqlStatement = this.sqlConnection.prepareStatement("SELECT * FROM Users WHERE username=?");
sqlStatement.setString(1, "Fellixombc");
ResultSet result = sqlStatement.executeQuery();
int userId = 0;
while(result.next()) {
System.out.println("TRUE");
userId = result.getInt("id");
System.out.println(result.getString("username"));
}
result.close();

Essentially, you want to store the username, correct?
Your current query will retrieve all information on relative to a username. It's what a SELECT query does, it retrieves.
If you need to create a new user, use:
INSERT INTO Users (username) Values ('Fellixombc');
I should tell you that you might need to provide more information in this query, depending on what other fields your Users table has.
EDIT:
In your select statement, you have an open single quote.
"SELECT * FROM Users WHERE username='Fellixombc"
should be
"SELECT * FROM Users WHERE username='Fellixombc'"
To avoid issues with SQL injection, consider the prepareStatement function.

Try doing a trim on your username field. Its possible there's a spurious space somewhere in the data thats causing your where clause to fail.
"SELECT * FROM Users WHERE trim(username) ='Fellixombc'"
Also, agree with #MPelletier. You should definitely be using PreparedStatements.

Related

Avoid SQL duplication in JDBC

Im trying to avoid SQL duplication. I found this code here how to prevent duplication. Java,SQL which is successful. I know rs.next will move the cursor, but how does it help avoid duplication (does it compare every value)? What is done is just checking is there another row and if there return true right?
Connection conn = // Connect to the database...
PreparedStatement ps =
conn.prepareStatement("SELECT username FROM login where username = ?";
ps.setString(1, value1);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
JOptionPane.showMessageDialog
(null,"username is already existed! please create new username.");
}
Your code is quite straightforward. You make a query that fetches ALL rows of the table login where username = XXX. Then you check whether there is any data in the ResultSet by executing the rs.next() function. This function returns a boolean value that is true when there is yet more data in the rs and false when there is no more data.
As you said, it also moves the cursor.
Does it compare every value(row)?
Yes. Your query looks every row up and checks whether username = XXX

Retrieve two values from the same row using a single select statement

Why can't I retrieve two values from different fields but same row?
If I write this, it works perfectly.
String sql = "SELECT * FROM soal ORDER BY RAND() LIMIT 1";
ResultSet rs = st.executeQuery(sql);
String question = rs.getString("questions");
But after I add this
String hint = rs.getString("hint_questions");
It won't work.
NOTE: I need two Strings, question, and hint from the same row and class for different purpose. So I have to use single select query SQL so that value from question and hint is related (from the same row).
You can try Either of the solution:
String var = rs.getString(1);
through index
Or
String var = rs.getString("column_name");
through column name

Assigning resultset column value to a variable for use in another SQL Statement?? Java

I am creating a data centric webservice in Java for deployment to Glassfish. All of my methods so far are working correctly except for one.
I am attempting to assign a value from a result set to a variable to use in another SQL statement as per the below code. I am not sure if its possible, or if perhaps my SQL is wrong, but any ideas would be appreciated.
ResultSet rset1 = stmt1.executeQuery("SELECT *
FROM WorkOrder
WHERE WorkOrderID = '"+workOrderID+"'");
Integer custID = rset1.getInt(3);
ResultSet rset2 = stmt2.executeQuery("SELECT *
FROM Customer
WHERE CustID = '"+custID+"'");
Integer quoteID = rset1.getInt(2);
ResultSet rset3 = stmt3.executeQuery("SELECT *
FROM Quote
WHERE QuoteID = '"+quoteID+"'");
What you posted can and should be done in a single query - less complex, and less [unnecessary] traffic back & forth with the database:
SELECT q.*
FROM QUOTE q
WHERE EXISTS (SELECT NULL
FROM CUSTOMER c
JOIN WORKORDER wo ON wo.custid = c.custid
WHERE c.quoteid = q.quoteid
AND wo.workorderid = ?)
The reason this didn't use JOINs is because there'd be a risk of duplicate QUOTE values if there's more than one workorder/customer/etc related.
Additionally:
Numeric data types (quoteid, custid, etc) should not be wrapped in single quotes - there's no need to rely on implicit data type conversion.
You should be using parameterized queries, not dynamic SQL
You foget to invoke ResultSet.next().
if(rset1.next())
{
Integer custID = rset1.getInt(3);
....
}
The note provided by OMG Ponies was really important to take note of, but does not really answer the question. AVD was also correct. I've cleaned it up a bit and included prepared statements. Please use prepared statements. They will help you sleep at night.
PreparedStatement pstmt1 = con.prepareStatement(
"SELECT * FROM WorkOrder WHERE WorkOrderID = ?");
PreparedStatement pstmt2 = con.prepareStatement(
"SELECT * FROM Customer WHERE CustID = ?");
PreparedStatement pstmt3 = con.prepareStatement(
"SELECT * FROM Quote WHERE QuoteID = ?");
pstmt1.setInt(1, workOrderId)
ResultSet rset1 = pstmt1.executeQuery();
// test validity of rset1
if(rset1.next()) {
pstmt2.setInt(1, rset1.getInt(3))
ResultSet rset2 = pstmt2.executeQuery();
// test validity of rset2
if(rset2.next()) {
pstmt3.setInt(1, rset1.getInt(2))
ResultSet rset3 = pstmt3.executeQuery();
}
}

ms access database with java

I am creating a java program, with which I am editing into a Microsoft Access Database. I have a certain case, in which I need to search if a certain record already exists in my table, if it does, I want to update it, and if not, I want to create it from scratch.
I have found this piece of code:
IF EXISTS (SELECT * FROM USERS WHERE USERID=#UID) select 1 else select
This code gives me an error, saying that a SELECT, UPDATE or DELETE statement was expected.
In a code that I have tried my self, I have done the following:
try{
s = con.createStatement();
s.executeQuery("SELECT * FROM table WHERE date='" + today + "'");
rset = s.getResultSet();
if (rset.getString("date") == null){
s = con.createStatement();
s.executeUpdate("INSERT INTO table VALUES ('" + today + "','" + cflow + "','" + vat + "','" + cnn + "')");
}
}
catch (SQLException exp)
{
System.err.println(exp);
}
But with this code, when the record does not exist yet, the user input is not updated inside the database.
Thanks for your time :)
1st: If I can remember right, then is
IF EXISTS (SELECT * FROM USERS WHERE USERID=#UID) select 1 else select
an incomplete transact sql statement -used by the sql engine from a database system.
2nd:
if (rset.getString("date") == null){}
you should avoid this way, because there is a good chance to get a Nullpointer Exception.
In my eyes a better one is a test the size of resultset for zero or the resultset it self for the value of NULL.
In case the UPDATE statement won't also be executed, check your SELECT statement using the database engine -Ms Access, SQL Server, etc.- directly. The advantage is you can exclude a mistake in your SELECT query.
What about this?
SELECT IF EXISTS (SELECT * FROM USERS WHERE USERID=#UID) THEN 1 ELSE 0 END
or
SELECT IF(EXISTS (SELECT * FROM USERS WHERE USERID=#UID), 1, 0)
(I'm not sure about the real syntax here.)
(rset.getString("date") == null)
should be
(!rset.next())
rset is positioned 'before' the first result that gets returned. next() returns true if there was a 'next' result to get.
Also, what datatype is your 'date' variable? There's no guarantee that a date.toString() will format the date correctly for MS-Access version of SQL.
Rather, prepare a statement
PreparedStatement ps = connetion.prepareStatement("SELECT * from table where date=?");
and set the date like
ps.setDate(1, date);
then issue the query using the prepared statement.
That saves any toString() issues. (I haven't compiled this, it almost certainly won't work as-is, but the idea is there).
Here is what i used to find the last ID in a table. IF the table is empty the no ID will be returned. If table is populated then i needed the next ID for new record.
ResultSet mn = stmt.executeQuery("SELECT MAX(ExamID)FROM ExamResults");
if (mn == null){
jTextField1.setText("1");
} else{
while (mn.next()) {
int lastID =Integer.parseInt(""+(mn.getObject(1)));
jTextField1.setText(""+(lastID+1));
}
}
// close the objects
mn.close();
stmt.close();
conn.close();

Prepared statement fails, but SQL console works

I am working on a project for uni (happens to be due in 14 hours) and I am at a sticking point. It is a web based web store running in eclipse on apache tomcat and derby.
I have a prepared statement that checks for a user name and passwordhash, no matter what I try this statement returns 0 rows. The same sql runs in the sql scratch pad and returns what is expected.
I have used the debugger to inspect the prepared statement object and the query seems fine. The ?'s in the text are still in place rather than filled with the variables, but that seems normal. I have also tried to run the exact same hand written sql from the console, but without any luck.
The query I run in the sql console is
SELECT * FROM username WHERE username='user#system.com' AND passwordhash='passwordhash'
The prepared statments look like this.
PreparedStatement pstmt = db.prepareStatement("SELECT * FROM reallynice.username " +
"WHERE emailaddress=?" +
" AND passwordhash=?");
pstmt.setString(1,username);
pstmt.setString(2, username + ":" + passwordLogin);
I am at the point where I have tried everything, and have run out of searches to make. I know this is a uni project and the standard reply is to give people somewhere to look. At this point I need spoon feed a path to go down.
EDIT Here is some more background, I have tried running a known working query in this pipeline and it also fails to return any rows.
public static User getUser(String username, String passwordHash) {
DBBean db = new DBBean();
System.out.println("Logging in for username " + username + " and password " + passwordHash);
try {
ResultSet rs;
PreparedStatement pstmt = db.prepareStatement("SELECT * FROM reallynice.username " +
"WHERE emailaddress=?" +
" AND passwordhash=?");
pstmt.setString(1,username);
pstmt.setString(2,passwordHash);
//PreparedStatement pstmt = db.prepareStatement("SELECT * FROM reallynice.product");
//PreparedStatement pstmt = db.prepareStatement("SELECT * FROM reallynice.username WHERE emailaddress='user#me.com' AND passwordhash='megahashstring'");
rs = pstmt.executeQuery();
System.out.println("Rows returned\t" + rs.getRow());
if(rs.getRow() < 1)
return null;
int id = rs.getInt("uid");
String name = rs.getString("name");
String emailaddress = rs.getString("emailaddress");
String password = rs.getString("passwordhash");
boolean isAdmin = false;
pstmt = db.prepareStatement("SELECT * FROM reallnice.admin WHERE uid= ?");
pstmt.setInt(1, id);
rs = pstmt.executeQuery();
if(rs.getMetaData().getColumnCount() > 0)
isAdmin = true;
return new User(id,isAdmin,name,emailaddress,password);
} catch(Exception ex) {
System.out.println(ex);
}
return null;
}
I have also included the other queries I have tried for this.
Whenever I see someone having an experience like this: "no matter what I try this statement returns 0 rows," there are two possible reasons that come immediately to mind:
1) You aren't using the database you think you are. Derby's connection URL, if you say ";create=true", will quite happily make a new, empty database when you connect, if it doesn't find an existing database in the location you expect. This sort of problem arises from a confusion over where the databases are created; a database with a relative name will be created in whatever directory turns out to the be derby.system.home of the Derby instance that gets that connection URL. So check to see if you are using a different current working directory, or for some other reason are connecting to a different database than you think you are.
2) You aren't using the schema you think you are. Derby will quite happily create multiple schemas, and each schema has a separate set of tables, so if you are initially connecting as user A, and then later connect as user B, and don't issue SET SCHEMA, then user A and user B have completely separate sets of tables and so you won't be accessing the tables that you think you are. So check to see if you are connecting as the same user and using the same schema when you connect to the database.
Try changing how you display your logging statement
System.out.println("Rows returned\t" + rs.getRow());
getRow() returns the current row number, not how many records were returned. In order to user getRow() to count the number of entries in the result set you would need to move the pointer of the result set to the last entry.
You have also, not called next() yet, which means you aren't pointing at anything (and most likely the reason you always see 0 as the number). Try using
while(rs.next()){ //go through the entire ResultSet}
or
if(rs.next()) { //access the first record in the ResultSet}
So over all, if you change your code to something like the following you may have better results.
rs = pstmt.executeQuery();
if(rs.next()){
System.out.println("Processing Row " + rs.getRow());
//continue on
}else{
System.out.println("No Records");
}
If you have set your table where the username is a unique key, you can be assured this will return 0 or 1 row. Otherwise use the while() option instead of if()
EDIT::
Also as a side note, because you are not calling next()
if(rs.getRow() < 1)
return null;
will always be 0, which returns null from your method.

Categories

Resources