Getting the sql exception that says: Too few parameters. Expected 1 - java

java.sql.SQLException: [Microsoft][ODBC Microsoft Access Driver] Too few parameters. Expected 1 This is a small piece of my server-client program which retrieves data from an access database. I am getting the Exception mentioned before and do not know how to resolve it. I have tried putting the column names into square brackets and a few other suggestions that i could find from similar questions but with no luck. Does anyone know what i have done wrong?And i believe the mistake is within the "query" String but again, do not know what to do to fix it.
class Protocol {
public static String processInput(String input) {
System.out.println("Test");
String choice = "";
String index = input.substring(0, input.indexOf("|"));
switch (index) {
case "1":
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection connect = DriverManager.getConnection("jdbc:odbc:Project");
Statement state = connect.createStatement();
String search = input.substring(input.indexOf("|") + 1, input.length());
String query = "SELECT Movies.[movie_name], Genre.[genre_name] " + "FROM Movies, Genre "
+ "WHERE Movies.[genre_id] = Genre.[genre_id] " + "AND Movies.[movie_name] = '"
+ search + "'";
ResultSet results = state.executeQuery(query);
while (results.next()) {
choice = choice + results.getString(1) + "|" + results.getString(2) + "|";
}
if (choice.equals("")) {
choice = "0";
}
} catch (SQLException | ClassNotFoundException e) {
JOptionPane.showMessageDialog(null,e,"Error", 0);
} break;

Related

How to update a row of entries in a database (JavaDatabase) that is connected to my JTable?

I am making a program without knowing much about programming... I used some youtube videos to help me.
My program is made for a chef that can edit users & food and gather ratings and suggestions from the inspector. The chef's section of editing users' details works.
However, the inspector's rating does not as it throws an error: SQLSyntaxException: Encountered "Vegetarian" at line 1, column 65. I believe it is because of getting the rating value (which is int) in a wrong way...
'
public void getConnection(){
try{
myconObj = DriverManager.getConnection("jdbc:derby://localhost:1327/MyApp", "Me", "Me");
mystatObj=myconObj.createStatement();
myresObj=mystatObj.executeQuery("Select * from Me.Food");
tableRateFood.setModel(DbUtils.resultSetToTableModel(myresObj));
}
catch (SQLException e){
e.printStackTrace();
}
}
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
try{
String sql = "update Me.Food set Name = '" + nameText.getText()
+ "',Type = '" + typeText.getText()
+ "', Rating = '" + ratingText.getText()
+ ", 'Vegetarian = '" + vegetarianText.getText()
+ "', ShownOnMenu = '" + showText.getText()
+ "' where Id = " + idText.getText();
//tried the following... did not work either
/*+ " Rating = " + Integer.parseInt(ratingText.getText()));*/
Statement update= myconObj.createStatement();
update.executeUpdate(sql);
JOptionPane.showMessageDialog(null, "Updated successfully!");
}
catch(SQLException E){
E.printStackTrace();
}
getConnection();
}
Your forgot a quote in ", 'Vegetarian = '"
Talking about building query strings, you should avoid +-ing values and rely on prepared statements with sql parameters instead. Allows the database to cache the query and avoids sql injection attacks. And spares you formatting headache, think about date values.

How to concatenate sql query in java?

I'm beginning to learn sql and java and I have a problem.
The logic for the code is:
The first part of the sql statement should be "a.stdn_code_ts" and as more elements (in this case student code) are included, I need to concatenate with and OR-Statement.
student codes could be a single value or a range, say for example: '567777' is valid as well as '567777-876677'.
If it is single value, just add "=" then the student code. In the example if the user entered '567777' then the query should be something like "a.stdnt_code_ts = '567777'"
If it is a range, add the first student code then "BETWEEN" second code. I.e.: if the user entered '567777-876677', the query should be "a.stdnt_code_ts BETWEEN '567777' AND '876677'".
and as I mentioned above, if there are 2 or more student codes the query should be concatenated with an "OR a.stdnt_code_ts" then checks again if it is a single value or a range.
I already have this code and got stuck:
private void formatStudentCode(Connection connection) throws Exception {
studentCode = "a.stdnt_code_ts ";
for(int i=0; i < stdntCode.size(); i++) {
if (stdntCode.get(i).indexOf("-")==-1) {
studentCode += "= '" + stdntCode.get(i) + "'";
}
else {
String [] range=stdntCode.get(i).split("-");
studentCode += "BETWEEN '" + range[0] + "' AND '" + range[1] +
"'";
}
}
}
First, this code is incomplete, so I'll need to make some guesses. But let's try.
Let's fix the loop first:
String sql = "SELECT * FROM students";
List<String> terms = new ArrayList<>();
List<String> arguments = new ArrayList<>();
// Don't need index here, for each loop is better
for (String code : codes) {
// No need for IndexOf
if (code.contains("-")) {
terms.add("stdnt_code_ts between ? and ?");
String[] split = code.split("-");
arguments.add(split[0]);
arguments.add(split[1]);
}
else {
// Don't concatenate SQL query parameters
terms.add("stdnt_code_ts = ?");
arguments.add(code);
}
}
Now to put our OR:
if (terms.size() > 0) {
sql += " WHERE " + Strings.join(terms, " OR ");
}
Now to add actual parameters for each question mark:
PreparedStatement preStmt = conn.prepareStatement(sql);
int count = 0;
for (String code : arguments) {
preStmt.setString(++count, code);
}
And finally to execute the query:
ResultSet rs = preStmt.executeQuery();
Note that I'm not running this code, so I may miss a line or two, but that's the general idea of how it should be done correctly.

Using MySQL by Java

I'm coding some database transactions by using java. I'm sending a query using java. I think it has no problem with it. And if I send the query at prompt, it is working.
This method is updating book quantity.
private static void updateBquantity(int bqt, String bname) {
Connection con = makeConnection();
try {
Statement stmt = con.createStatement();
System.out.println(bqt + " " +bname);
//this part is making problem
stmt.executeUpdate("update books set bookquantity = bookquantity -" + bqt + "where bookname = '" + bname + "';");
System.out.println("<book quantity updated>");
} catch (SQLException e) {
System.out.println(e.getMessage());
System.exit(0);
}
stmt.executeUpdate("update books set bookquantity = bookquantity -" + bqt + "where 도서이름 = '" + bname + "';");
This part is making problem.
Other queries using this form is working.
The compiler says :
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near 'bookname = 'Davinci Code'' at line 1
Help me.
I'm confused with bookname = 'Davinci Code, where is bookname in your query? No matter what, in this query, you missed a blank before where, try this:
stmt.executeUpdate("update books set bookquantity = bookquantity -" + bqt + " where 도서이름 = '" + bname + "';");

SQL command not properly ended with select

I'm working with Oracle SQL Developer with a Java application. I want to ask to the DB this query:
select * from vocabolario, vocaboli_help where verbo=1 and
vocabolario.id = vocaboli_help.id and vocaboli_help.usato = 0
The query works when I run it from SQL developer, but when run it from Eclipse with the stmt.executeQuery(string), where stmt is a Statement object, it throws the following exception: SQL command not properly ended.
I put also a semicolon at the end of the string, but it doesn't work.
I used the stmt.executeQuery(string) with other queries and in those cases there were no problems. The only difference I can see is that in this case I have where condition in AND.
Java code :
private final static String NOME_DATABASE = "VOCABOLARIO", NOME_DATABASE_HELP ="VOCABOLI_HELP";
String type ="verbo";
String query = "SELECT * FROM " + NOME_DATABASE + ", " + NOME_DATABASE_HELP +" WHERE " + type + " = 1 " +
"AND " + NOME_DATABASE +".ID = " + NOME_DATABASE_HELP +".ID AND "+NOME_DATABASE_HELP+".USATO = 0";
System.out.println(query);
int cont = 0;
String result="";
try {
ResultSet res = statement.executeQuery(query);
while(res.next()) {
String cod = res.getString("ID").trim();
String voc = res.getString("VOCABOLO").trim();
String trad = res.getString("TRADUZIONE").trim();
if(cont == n)
result = cod + "," + voc + "," + trad;
cont++;
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
`
select * from vocabolario vo
left join vocaboli_help voh
on vo.id= voh.id
where v.verbo=1 AND voh.usato=0
You just need a simple join.
VOCABOLI_HELP or vocabolario_help your code and your post different
Thank you all, the problem was in the name of the second table, but I think it depends on Java code sintax, as #are suggested.
I updated the code:
private static final String NOME_DATABASE_HELP = "VOCABOLIHELP"
I also modified the table name in the DB and now it works. I think there are issues with the underscore in the name (the problem is only in Java as I said), I don't know why.

Design Pattern for writing file with minimum memory consumption

I need to write a file by reading an xml, containing format information and values to be fetched from database. I am working on large number of records(200,000).
I have tried keeping all the data in memory but got out of memory error.
I have tried hitting database again and again but then I got performance issue. As queries being hit again and again decreases performance.
Steps involved for the process:
hitting db to get all records for which file is to be created
reading xml file using Jaxb
creating map of all the data obtained from step 1.
iterating over map obtained from step1
deriving what data need to be displayed from format object created
in step 2
appending result in a string for each record and then writing same
into file
Though, finally I resolved this by reading a predefined count of data once and write file for this and then work on next bunch. But I have not followed any design pattern for this.
Is there a design pattern that uses minimum memory and let me write file efficiently?
The design pattern is called Pagination (using a cursor). When you send a query to Oracle DB for example, the default number of results in the resultset returned is 50. Only when you ask the resultset to get next() it'll return the next 50 results. That's how most DBs work and designed to be efficient for such a pattern (see this code example):
public static void viewTable(Connection con, String dbName)
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(); }
}
}
So, you can open the file, and write every "page" of results that you're getting, ask for the next page etc. Once you're done - close the file.
If you are writing to XML, I suggest writing out each record as you read it in. This way you only need enough memory for one record at a time and it doesn't matter how many records you have.
e.g.
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()) {
xmlFile.println("<coffee>\n" +
"<coffeename>" + rs.getString("COF_NAME") + "</coffeename>\n" +
"<supId>" + rs.getInt("SUP_ID")+ "</supId>\n" +
"<price>" + rs.getFloat("PRICE") + "</price>\n" +
"<sales>" + rs.getInt("SALES") + "</sales>\n" +
"<total>" + rs.getInt("TOTAL") + "</total>\n" +
"</coffee>");
}
} catch (SQLException e ) {
JDBCTutorialUtilities.printSQLException(e);
} finally {
if (stmt != null) { stmt.close(); }
}
You may need to escape out strings in case they contain special characters.

Categories

Resources