My ResultSet will only print first row - java

I have a ResultSet that I know contains 8 rows of data because I checked it with a direct query of the DB. My code will only display the first row.
If anyone can give me some help I would greatly appreciate it. The first row is what should I expect it to be, I just don't know how to get it to move on to print subsequent rows.
term= Integer.parseInt(args[1]);
// Select a list of the surveys that fall under the term
query= "Select cid,subject,course_number,instructor_id from Courses where term=" + Integer.parseInt(args[1]);
result = statement.executeQuery(query);
String query2="";
while(result.next())
{
// Pull in the data
cid = result.getInt("cid");
subject = result.getString("subject");
courseNumber= result.getInt("course_number");
instructorId= result.getInt("instructor_id");enter code here
// Get the instructors last name
query2= "Select last_name from Instructors where fid=" + instructorId;
subResult= statement.executeQuery(query2);
while(subResult.next())
{
instructorLName= subResult.getString(1);
}
// Get the averages and num submitted
query2= "Select num_submitted, sum_q1, sum_q2, sum_q3, sum_q4, survey_id from surveys where cid=" + cid;
subResult= statement.executeQuery(query2);
while(subResult.next())
{
numSub= subResult.getInt(1);
sumQ1= subResult.getInt(2);
sumQ2= subResult.getInt(3);
sumQ3= subResult.getInt(4);
sumQ4= subResult.getInt(5);
surveyId= subResult.getInt(6);
}
// Print everything necessary
System.out.println( surveyId + " " + term + " " + subject + " " + courseNumber +
" " + instructorLName + " " + sumQ1/numSub + " " + sumQ2/numSub + " " + sumQ3/numSub
+ " " + sumQ4/numSub);
}
}

Not sure, but the problem might be that you are using same Statement object to execute different queries. Create separate statement instances for query and query2 and try.

Related

How do I access and display specific records in a MySQL relational-database using JDBC/Java?

I have a project-management-system that used to read data from text-files, but is now being changed to read data from a database.
I am trying to figure out how to display specific information in different tables based on the project number in the projects table.
All of the tables in my database are related to this project table.
A Visual Presentation of My Database
ERD for my database:
My Problem
Neatly display all the information for for project.
What I am trying to figure out is, how do I get a specific record in one table, based on the foreign-keys in my projects table?
For example, if a project has an architect with the architect_name "Bryan" , then how do I display the architect details for just "Bryan"?
My Code for my displayAll method
public static void viewAllProjects() {
// Calling the 'connectionAttempt' method to connect to the 'ebookstore' database.
Connection connection = connectionAttempt();
PreparedStatement ps;
// Using a try- catch block to print the data for a specific record in the 'books' table.
try {
// Creating and using a normal statement to select the specific record in the database.
Statement statement = connection.createStatement();
// SQL select statement
String q = "select * from architect\n" +
"union all\n" +
"select * from contractor\n" +
"union all\n" +
"select * from customer" +
"union all\n" +
"select * from shopping_basket\n" +
"union all\n" +
"select * from projects\n" +
"union all\n" +
"select * from building_info";
ResultSet rs = statement.executeQuery(q); // Executing statement
// Printing ResultSet
if (rs.next()) {
String projectDetails = "\nProject Number: " + rs.getString("project_number") + "\n" +
"Project Name: " + rs.getString("project_name") + "\n" +
"Type of building: " + rs.getString("HERE") + "\n" +
"ERF Number: " + rs.getString("HERE") + "\n" +
"Physical Address: " + rs.getString("physical_address") + "\n" +
"Total fee charged for project: " + rs.getString("HERE") + "\n" +
"Total amount already paid: " + rs.getString("HERE") + "\n" +
"Deadline of the project: " + rs.getString("deadline") + "\n" +
"Project Finalised: " + rs.getString("finalised") + "\n" +
"\nArchitect Name: " + rs.getString("architect_name") + "\n" +
"Architect Telephone Number: " + rs.getString("id") + "\n" +
"Architect Email-Address: " + rs.getString("id") + "\n" +
"Architect Physical Address: " + rs.getString("id") + "\n" +
"\nContractor Name: " + rs.getString("contractor_name") + "\n" +
"Contractor Telephone Number: " + rs.getString("id") + "\n" +
"Contractor Email-Address: " + rs.getString("id") + "\n" +
"Contractor Physical Address: " + rs.getString("id") + "\n" +
"\nCustomer Name: " + rs.getString("HERE") + "\n" +
"Customer Telephone Number: " + rs.getString("HERE") + "\n" +
"Customer Email-Address: " + rs.getString("HERE") + "\n" +
"Customer Physical Address: " + rs.getString("HERE") + "\n" +
"----------------------------------\n";
System.out.println(projectDetails);
} else {
System.out.println("Record Not Found...");
}
connection.close();
} catch (Exception e) {
System.out.println(e);
}
}
My code for the connectionAttempt method works, as I used it before.
Please let me know if there are any other details I can provide.
This project is not going to work out until you learn SQL. Once you do, you'd know that UNIONing together every row in the entire database is a crazy way to work. This attempts to pump over all data in your database in an incredibly inefficient way.
If a project has an architect with the architect_name "Bryan" , then I how do display the architect details for just "Bryan".
An SQL statement along the lines of SELECT * FROM architect WHERE architect_name = ? (make that your PreparedStatement), then use ps.setString(1, "The name of the architect goes here"); to set the query parameters, then run it, and voila.
You may want to 'marshal' the returned data into a specialized java object that represents exactly the data returned, because working with some java class is a lot simpler than having to run a ton of rs.getString... style statements. more on that later.
If you want all projects that brian made, then there's no way to tell unless you explain to us how your database is designed. But it'll look something along the lines of:
SELECT p.* FROM projects p
INNER JOIN architect a ON p.architect = a.unid
WHERE a.architect_name = ?
You need to know about SQL - search the web for any SQL tutorial.
You also need to interact with it from the java side. You're currently doing raw JDBC - not recommended. Read up on JDBI or if you prefer, JOOQ. These also make that marshalling thing a lot simpler.

sql syntax error, but concatenated text runs fine in Datagrip

I'm trying to run a query, but I get an error when running it.
However, I'm using Intellij and when I use the copy string concatenation to clipboard feature, and run the query in the datagrip, the query runs fine (after putting in the parameters)
The error I am getting is "ERROR: syntax error at or near "tstoredarticle"\n Position: 199"
I find it a bit weird that it's showing there's a line change, after tstoredartiacle but besides that I don't see what's wrong.
What could be some issues that could cause a problem like that?
my query in intellij looks like this:
private ResultSet getHuaweiSqlQuery(Integer intBrandID, Integer intStorageID, Vector<Integer> vecArticleTypes, int iCurrencyID, int iContactSupplierID, int secondaryStorage, BigDecimal exchangeRate) throws SQLException {
return Hibernate3To4Utils.getConnection(session).createStatement().executeQuery("SELECT storedarticleid, "
+ " CASE WHEN storedarticle_storageid = " + intStorageID
+ " THEN id_storedarticleid_replacement ELSE"
+ " (SELECT COALESCE(id_storedarticleid_replacement, storedarticleid)"
+ " FROM etel.tstoredarticle x"
+ " WHERE tstoredarticle.storedarticle_articleid = x.storedarticle_articleid"
+ " AND x.storedarticle_storageid = " + intStorageID + ")"
+ " END as id_storedarticleid_replacement,"
+ " articlename,"
+ " articledescription, CASE WHEN price IS NULL THEN last_innprice*" + exchangeRate
+ " ELSE price END as last_innprice, id_modelids[1] as order_modelid, storedarticleamount-amount_in_order-amount_waiting as disponibelt,"
+ " amount_in_order, amount_in_bestilling, sum(tusedarticle.amount) as ant_artikler, articleid,amount_waiting, location"
+ " FROM etel.tstoredarticle"
+ " INNER JOIN etel.tarticle as b ON storedarticle_articleid = b.articleid"
+ " LEFT JOIN etel.tusedarticle ON usedarticle_storedarticleid = storedarticleid"
+ " AND ((tusedarticle.datesnap >= CAST(now() as date)-" + LOOK_BACK_DAYS
+ " AND usedarticlefromstorage = true) OR waiting = true)"
+ " LEFT JOIN etel.torder ON usedarticle_orderid = orderid AND torder.id_serviceplaceid = " + Constants.SERVICEPLACE
+ " LEFT JOIN etel.tsupplier_price ON id_articleid = b.articleid"
+ " AND tsupplier_price.id_serviceplaceid = " + Constants.SERVICEPLACE
+ " AND tsupplier_price.id_currencyid = " + iCurrencyID
+ " AND tsupplier_price.id_contactid_supplier = " + iContactSupplierID
+ " LEFT JOIN etel.tusedarticle as last_used on storedarticleid = last_used.usedarticle_storedarticleid"
+ " AND last_used.usedarticleid = (select MAX(latest_usedarticle.usedarticleid) from etel.tusedarticle as latest_usedarticle where"
+ " latest_usedarticle.usedarticle_storedarticleid = storedarticleid)"
+ " WHERE storedarticle_storageid IN(" + intStorageID + ", " + secondaryStorage + ") AND b.id_brandid = " + intBrandID
+ " AND id_articletypeid IN (" + getStringFromArray(vecArticleTypes.toArray()) + ")"
+ " AND tstoredarticle.passive <> true"
+ " GROUP BY storedarticleid,id_storedarticleid_replacement, articlename, articledescription, last_innprice, id_modelids[1],"
+ " storedarticleamount, amount_in_order, amount_in_bestilling, articleid,price,amount_waiting, location, last_used.datesnap"
+ " ORDER BY id_storedarticleid_replacement, storedarticleid");
}
and here's the same query after using the copy string concatenation to clipboard feature:
(this runs fine)
SELECT storedarticleid,
CASE WHEN storedarticle_storageid = ?
THEN id_storedarticleid_replacement ELSE
(SELECT COALESCE(id_storedarticleid_replacement, storedarticleid)
FROM etel.tstoredarticle x
WHERE tstoredarticle.storedarticle_articleid = x.storedarticle_articleid
AND x.storedarticle_storageid = ?)
END as id_storedarticleid_replacement,
articlename,
articledescription, CASE WHEN price IS NULL THEN last_innprice*?
ELSE price END as last_innprice, id_modelids[1] as order_modelid, storedarticleamount-amount_in_order-amount_waiting as disponibelt,
amount_in_order, amount_in_bestilling, sum(tusedarticle.amount) as ant_artikler, articleid,amount_waiting, location
FROM etel.tstoredarticle
INNER JOIN etel.tarticle as b ON storedarticle_articleid = b.articleid
LEFT JOIN etel.tusedarticle ON usedarticle_storedarticleid = storedarticleid
AND ((tusedarticle.datesnap >= CAST(now() as date)-42
AND usedarticlefromstorage = true) OR waiting = true)
LEFT JOIN etel.torder ON usedarticle_orderid = orderid AND torder.id_serviceplaceid = ?
LEFT JOIN etel.tsupplier_price ON id_articleid = b.articleid
AND tsupplier_price.id_serviceplaceid = ?
AND tsupplier_price.id_currencyid = ?
AND tsupplier_price.id_contactid_supplier = ?
LEFT JOIN etel.tusedarticle as last_used on storedarticleid = last_used.usedarticle_storedarticleid
AND last_used.usedarticleid = (select MAX(latest_usedarticle.usedarticleid) from etel.tusedarticle as latest_usedarticle where
latest_usedarticle.usedarticle_storedarticleid = storedarticleid)
WHERE storedarticle_storageid IN(?, ?) AND b.id_brandid = ?
AND id_articletypeid IN (?)
AND tstoredarticle.passive <> true
GROUP BY storedarticleid,id_storedarticleid_replacement, articlename, articledescription, last_innprice, id_modelids[1],
storedarticleamount, amount_in_order, amount_in_bestilling, articleid,price,amount_waiting, location, last_used.datesnap
ORDER BY id_storedarticleid_replacement, storedarticleid
Don't use string concatenation with dynamic text values to build a SQL statement.
For one, if the text values are supplied by a user, you're leaving yourself vulnerable to SQL injection attacks, allowing hackers to steal your data and delete your tables.
But you also have problems getting the text values quoted and escaped correctly.
Instead, use a PreparedStatement, where you place ? markers anywhere a dynamic value needs to go. That is the string in the clipboard.
Example: You're doing:
String name = "John";
String sql = "SELECT * FROM Person WHERE name = " + name;
That gives you this text at runtime:
SELECT * FROM Person WHERE name = John
which is wrong, because the text value needs to be quoted:
SELECT * FROM Person WHERE name = 'John'
You could try
String name = "John's Cross";
String sql = "SELECT * FROM Person WHERE name = '" + name + "'";
but that's also wrong, because this new text value has embedded quotes and would produce:
SELECT * FROM Person WHERE name = 'John's Cross'
To get it right, use a PreparedStatement:
String name = "John's Cross";
String sql = "SELECT * FROM Person WHERE name = ?";
PreparedStatement stmt = Hibernate3To4Utils.getConnection(session).prepareStatement(sql);
stmt.setParameter(1, name);
return stmt.executeQuery();
The JDBC driver will take care of any escaping needed, and thereby protects you from both SQL injection attacks and SQL syntax errors.

"ORA-01858: a non-numeric character was found where a numeric was expected" when writing a query in a java class

I have a web application where 3 inputs are taken from the user and after clicking search button results are displayed. The three inputs are; id (not unique), startdate and enddate. I want to be able to get the results in these situations: If the user enters
only id
only start date (enrolldate in db table)
only end date (graduationdate in db table)
id and start date
when all the fields entered together
In my StudentManager.java class I have a SQL string like below;
final String SQL_STU = " select "
+ " t.name,"
+ " t.surname, "
+ " t.lecture,"
+ " from studenttable t "
+ " where t.school = 'CHC' "
+ " and t.id = case when '" + studentInfo.getID() + "'" +" is null then t.id else '" + studentInfo.getID() + "' end "
+ " and t.enrolldate >= case when '" + studentInfo.getStartDate() + "' is null then t.enrolldate else to_date('"
+ studentInfo.getStartDate() + "', 'DD.MM.YYYY HH24:MI:SS') end "
+ " and t.graduationdate >= case when '" + studentInfo.getEndDate() + "' is null then t.graduationdate else to_date('"
+ studentInfo.getEndDate() + "', 'DD.MM.YYYY HH24:MI:SS') end " ;
I will execute this query and get the results into a result set.
I have a couple of problems with this code; for example when I comment out this part:
+ " and t.enrolldate >= case when '" + studentInfo.getStartDate() + "' is null then t.enrolldate else to_date('"
+ studentInfo.getStartDate() + "', 'DD.MM.YYYY HH24:MI:SS') end "
+ " and t.graduationdate >= case when '" + studentInfo.getEndDate() + "' is null then t.graduationdate else to_date('"
+ studentInfo.getEndDate() + "', 'DD.MM.YYYY HH24:MI:SS') end " ;
It works without errors but when I give all the inputs null (id, date1, date2) it displays nothing. Shouldn't it display all the results since there is no specific id? (User will not be able to submit 3 empty fields but I am curious why it does not work like the way I mentioned? )
The other thing is when I execute the whole code (with to_date parts) it gives the error in the title. But it does not give any error when I execute like this:
final String SQL_STU = " select "
+ " t.name,"
+ " t.surname, "
+ " t.lecture,"
+ " from studenttable t "
+ " where t.school = 'CHC' "
+ " and t.enrolldate >= case when '" + studentInfo.getStartDate() + "' is null then t.enrolldate else to_date('"
+ studentInfo.getStartDate() + "', 'DD.MM.YYYY HH24:MI:SS') end " ;
So in summary I couldn't write the query the way I wanted. I am not that experienced with queries. If you know any better way you can also suggest it since I have come to a dead end. I also tried something with NVL but I could not make it work also.
Notes:
ID, StartDate,EndDate are type string in my StudentInfo.java class
id is type varchar and dates are type date in database table.(PL/SQL)
The best answer to your question is to use a prepared statement:
String sql = "SELECT t.name, t.surname, t.lecture ";
sql += "FROM studenttable t ";
sql += "WHERE t.school = 'CHC' AND "
sql += "t.id = COALESCE(?, t.id) AND ";
sql += "t.entrolldate >= COALESCE(?, t.enrolldate) AND ";
sql += "t.graduationdate >= COALESCE(?, t.graduationdate)";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, studentInfo.getID());
ps.setDate(2, studentInfo.getStartDate());
ps.setDate(3, studentInfo.getEndDate());
ResultSet rs = ps.executeQuery();
while (rs.next()) {
// process a row
}
The reason why using a statement is preferred is that it frees you from having to manually marshal your Java date (and other type) variables into your Oracle SQL statement. Instead, the above code lets the JDBC driver worry about how to convert a Java date variable to the correct format in the actual SQL code. Also, statements allow you to write a SQL query with minimal concatenations, which reduces the chances for error and typos.
Note that you might have to call a setter other than PreparedStatement#setDate depending on the what getStartDate() and getEndDate() methods actually return in your Java code.

Sqlite Android Optimization

I have an application that works well. But I suspect that I can improve it if I optimize queries to the database. And I need suggestions.
This is part of my "select query":
private static final String SELECT = "SELECT " +
"dz.first_id AS first_id, " +
"dz._id AS _id, " +
"dz.att1 AS att1, " +
"dz.att2 AS att2, " +
"dz.att3 AS att3, " +
"dz.att4 AS att4, " +
"dz.att5 AS att5, " +
"d.var1 AS var1, " +
"d.name AS name, " +
"d.last_update AS last_update, " +
"d.image_url AS image_url, " +
"d.image_highlighted_url AS image_highlighted_url, " +
"d.var2 AS var2, " +
"d.type AS type, " +
"d.state AS state, " +
"d.sync AS sync, " +
"d.var3 AS var3 " +
"FROM table1 dz INNER JOIN table2 d " +
"ON d._id = dz.first_id ";
Cursor result = conn.rawQuery(SELECT, null);
*table1 and table2 have simple creation: only one _id integer PRIMARY KEY AUTOINCREMENT NOT NULL
It is useful to use views? Any other suggestion?
Thanks.
This query looks as cut and dry and they can get, I think your options are really either to see if you can somehow leave some unnecessary columns out of your select or alternatively to see that both dz.first_id and d._id have indexes setup. Perhaps add a index to dz with the following
CREATE INDEX index1 ON table1 (first_id);

Trouble with a line of SQL in my java program

So the program is the connecting to a .mdb file as our data base. I have written all the other code to the program and know it works fine but I am now having trouble with a complex SQL statement being passed as a parameter to a createQuery(Sring, int) method.
There are two tables
Person, which has Name, Id, City, State
Classes, which has Id, Course, Grade
The intended purpose of this line is to print out "Name and Id" from a table of Persons and also print "Course and Grade" from the Classes table. The query only prints entries with matching Id's(Person.Id = Classes.Id), in a specific Course('CSC 225'), and that have a Grade > 70.
We never were taught the SQL statements in any depth so my basic understanding has concocted the following lines of code.
String s = "SELECT " + personTableTitle + ".Name, " + personTableTitle + ".Id, " +
classesTableTitle + ".Course, " + classesTableTitle + ".Grade FROM " +
personTableTitle + " " + classesTableTitle + " WHERE " +
personTableTitle + ".ID = " + classesTableTitle + ".Id AND " +
"Course = 'CIS 225' AND " + classesTableTitle + ".Grade > 70 AND " +
personTableTitle + ".Id = ? AND " + classesTableTitle + ".Id = ?";
System.out.print(s); // Double check of my SQL Statement before passing
db.createQuery(s, 4);
I have been playing with this SQL statement since Wednesday night and haven't been having much luck.
I only see two problems. Sql needs commas between the table names in the FROM clause, i.e. ...FROM table1, table2 WHERE.... So change your line to
personTableTitle + ", " + classesTableTitle + " WHERE " +
This next one might not be a problem, but it's a good idea to include the table name in front of every field reference.
classesTableTitle + ".Course = 'CIS 225' AND " + classesTableTitle + ".Grade > 70 AND " +
You should definitely try your query directly on the database (console or GUI). Once your query is valid, you'll be able to translate it very quickly back into Java.
Otherwise, it's good practice to add an alias to tables; for example:
select *
from Person P, Classes C
where P.Name = 'joe' and P.id = C.id
You may also need to do an outer join to get your data (look at how to do joins for your database).
Here's what I would suggest for SQL code
String s = "SELECT P.Name, P.Id, ";
s = s + "C.Course, C.Grade ";
s = s + "FROM Person P ";
s = s + "JOIN Classes C ";
s = s + "ON P.ID = C.ID ";
s = s + "WHERE Course = 'CIS 225' AND C.Grade > 70;";
I split up each assignment into its own line.
Solved it everyone, thanks for the help.
I started rewriting it using the suggestions posted and came up with this as the string:
String s = "SELECT Person2.Name, Person2.Id, Classes.Course, Classes.Grade FROM Person2, Classes WHERE Classes.Id = Person2.Id AND Classes.Course = 'CIS 225' AND Classes.Grade >70";
It works so I can make it more presentable now. The reason I am using my variable names from java in the original post was that is what the teacher wanted. She is very stubborn and has taken off points from my material for things as simple as writings += whatever; instead of s = s + whatever;

Categories

Resources