I write a opration on java soap service to query the database and then show the data I have searched on client jsp page. However, I can't show it, the variable "rs" cannot change, I don't know why? could someone help me to find the troboule?
This is the opration i create on soap service:
#WebMethod(operationName = "query")
public String query(#WebParam(name = "parameter") String parameter) {
ResultSet rs;
try {
Connection con = data1.getConnection();
Statement statement = con.createStatement();
String QueryString;
QueryString = "SELECT * from stud where name= parameter";
rs = statement.executeQuery(QueryString);
while (rs.next()) {
System.out.println(rs.getInt(1) + " " + rs.getString(2) + "\n");
}
} catch (Exception ex) {
System.out.println("Unable to connect to batabase.");//TODO write your implementation code here:
}
//TODO write your implementation code here:
return null;
}
I'm not totally sure I understand your question. Maybe you mean that you can view the console output and this process that rs is an empty result set. You said rs cannot change, but you probable realize that rs stores the entire result set and you only assign it once, so it doesn't "change" if your code is working currently.
One obvious thing that is wrong is that parameter is a variable (in fact, a parameter!) But you include it inside the quotes as part of the query string. So regardless if the function input, you are searching the database for the name "parameter"
Related
I've got users trying to register to a site. before they can register their username of choice is searched for in an SQL database to make sure it doesn't already exist.
the problem is the names are never searched because the ResultSet always returns empty. I think it's the prepared statement.
I think my prepared statement isn't executing. I'm using executeQuery() to execute my statement because that's how I've been inserting the usernames without any problem. I got the search ResultsSet part if (rs.next())... from the method that inserts the usernames. Same with the String SQL and the prepared statement stuff.
String SQL = "SELECT * FROM users WHERE username='" + getUsername() + "'";
System.out.println(SQL);
// prints out SELECT * FROM users WHERE username='whatever I searched'
// so this String is valid
if (db.getConn() != null){
System.out.println("connected to database");
// always prints
}
PreparedStatement preparedStatement = db.getConn().prepareStatement(SQL);
// preparedStatement.setString(1, getUsername());
ResultSet rs = preparedStatement.executeQuery();
// userNameCounter = rs.getString("username");
// putting this here returns an sqlexception. empty set
if (preparedStatement != null){
System.out.println("ps != null");
// prints this
}
if (rs != null){
System.out.println("rs != null");
// prints this
}
if (!rs.next()){
System.out.println("!rs.next");
// prints this
}
if (rs.next()) {
userNameCounter = rs.getString("username");
System.out.println("rs.next()");
// doesn't print
// so the resultset is empty
if (!userNameCounter.equals(getUsername())) {
System.out.println("that username is unique");
return true;
}
}
preparedStatement.close();
incorrectLabels.setText("That username is already taken");
incorrectLabels.setVisible(true);
System.out.println("that username is already there");
// this always prints. it shouldn't
return false;
So executeUpdate() requires an int but I'm not sure what I would put there. And doing just execute() throws an error Requires ResultSet found boolean. I don't think there are any syntax errors since the table is called users. Everything I try just leads me back to an error resulting from an empty set. let me know if you need more code but this is where the error is happening.
Thanks!
You are issuing a query to the database when using the SELECT statement therefore you use the executeQuery() method.
What looks confusing is the userNameCounter variable you're using. Where is it declared and what is it declared as? It looks like it may be a Integer variable which would bring me to ask....what do you think the rs.getString("username") method returns?
As a matter of fact...what's with all the rs.next() conditions for all those if statements?
The whole thing is rather confusing. If you want to see if a User Name already exists within a database table then you might do it something like this:
if (db.getConn() == null){
throw new RuntimeException("Method Error! You Are NOT Connected To Database!");
}
String suppliedUserName = getUsername();
String dbUserName = "";
String SQL = "SELECT username FROM users WHERE username=?";
PreparedStatement preparedStatement = db.getConn().prepareStatement(SQL);
preparedStatement.setString(1, suppliedUserName);
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
dbUserName = rs.getString("username");
}
rs.close()
preparedStatement.close()
/* Below we use the equalsIgnoreCase() method. You
don't want a supplied User Name to be that close
or that similar to another User Name already in
Database. If you do then just use equals() method. */
if (dbUserName.equalsIgnoreCase(suppliedUserName)) {
System.out.println("The User name (" + suppliedUserName +
") is already in use. Try another User Name.");
return false;
}
else {
System.out.println("The User name (" + suppliedUserName + ") is Unique.");
return true;
}
Of course this code isn't tested and I assume you have your try/catch in place to handle any SQLException. I merely provide this code to give you an idea of how it can be accomplished.
I am using mySQL. As you see, the SQL statement is wrong at SELECT. So, I wonder what value the rs is?
I hope to get some advice. I thank you so much;
String sql = "SELCT * FROM user WHERE username = '" + username + "' and password = '" + password + "'";
ResultSet rs = stm.executeQuery(sql);
There would be no value because Statement.executeQuery(String) would throw a SQLException. As the linked Javadoc says,
Returns:
a ResultSet object that contains the data produced by the given query; never null
Throws:
SQLException - if a database access error occurs, this method is called on a closed Statement, the given SQL statement produces anything other than a single ResultSet object, the method is called on a PreparedStatement or CallableStatement
It will return you an exception having message like syntax error.
Easiest way to find is to debug your code by putting break points in code & examining / watching values of variables . Most IDEs have these debugging features. In addition to Elliott Frisch's answer, if I restructure your code like below then in case of invalid / incorrect SQL, control comes to catch block and you can see that value of rs remains null.
public void executeQuery(Connection conn, String username,String password) {
String sql = "SELCT * FROM user WHERE username = '" + username + "' and password = '" + password + "'";
ResultSet rs = null;
Statement stm = null;
try {
stm = conn.createStatement();
rs= stm.executeQuery(sql);
while(rs.next()) {
//Extract ResultSet here as per needed logic
}
} catch (SQLException e) {
// Your control comes here if query is wrong , put a break point at below line & examine value of rs
e.printStackTrace();
}finally {
// Close resources not needed after this method call like - result sets , statements & connection
}
}
Firstly statement won't execute, so next execution is depends on how you are going to handle that exception. So, if exception comes and if you handle also there will be null in ResultSet because no value assigned to it.
Code snippet:
On a button click, actionevent will be called
public void actionPerformed(ActionEvent e)
{
Function f = new Function();
Function is a nested class which i have used to establish the connection with the database.
The code snippet for function class is also provided in the end.
ResultSet rs = null;
String Cid ="cust_id";
String Pno="cust_phone";
String cat="cust_cat";
String start_date="st_date";
String Adv_amt="adv";
String Adv_end="end_date";
String Address="addr";
t2 is the Textfield name which i have used to get entry of customer name. I want to use this customer name as a PK to fetch all the other data about that customer from DB.
rs=f.find(t2.getText());
try{
if(rs.next())
{
t1.setText(rs.getString("cust_id"));
t3.setText(rs.getString("cust_phone"));
t4.setText(rs.getString("cust_cat"));
t5.setText(rs.getString("st_date"));
t6.setText(rs.getString("adv"));
t7.setText(rs.getString("end_date"));
t8.setText(rs.getString("addr"));
}
else
JOptionPane.showMessageDialog(null,"No data for this name");
}
catch(Exception ex)
{
JOptionPane.showMessageDialog(null,ex.getMessage());
}
}
Here is the code snippet for nested class Function which is inside the main class:
class Function{
Connection con=null;
ResultSet rs= null;
PreparedStatement ps = null;
public ResultSet find(String s)
{
try
{
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
con = DriverManager.getConnection("jdbc:oracle:thin:#Localhost:1521:xe","system","qwerty");
ps= con.prepareStatement("Select * from gkkdb where cust_name='?'");
ps.setString(1,s);
rs= ps.executeQuery();
}
catch(Exception ex)
{
JOptionPane.showMessageDialog(null, ex.getMessage());
}
return rs;
}
}
Please help figure out the problem.
Don't put the parameter placeholder ? in single quotes.
This:
ps = con.prepareStatement("Select * from gkkdb where cust_name='?'");
should be
ps = con.prepareStatement("Select * from gkkdb where cust_name = ?");
The ? is not recognized as a placeholder if you enclose it in single quotes.
Sorting out the bind variable will fix your immediate issue.
You should explicitly specify what columns you want selected and that way you'll only get what you need (someone might add a BLOB column later) and you'll get them in the right order (someone might change the table create script before running on another DB instance, although you are looking up the columns by name, a different order would only impact if you were using positional indexes).
Ditto on the other answer re: bind variables (i.e. no quotes)
Plus, "select * from" is never a good idea, ask your DBA.
Obviously your code is for example, but you should make sure you free up any resources (Connection, Statement, ResultSet) as soon as they are done with. Use Java 7 try-with-resources.
I am writing a query to load my data in a jlist
public void showtitle(){
DefaultListModel model = new DefaultListModel();
booklist.setModel(model);
try{
Class.forName("org.apache.derby.jdbc.ClientDriver");
Connection conn = DriverManager.getConnection("jdbc:derby://"+X, "APP", "app");
Statement stmt = conn.createStatement();
String query="SELECT TITLE FROM BOOK WHERE ISBN LIKE '%"
+ code.getText().toUpperCase()+"%' OR "
+ " TITLE LIKE '%"+name.getText().toUpperCase()+"%' ";
ResultSet rs = stmt.executeQuery(query);
while(rs.next()){
String isbn = rs.getString(1);
model.addElement(isbn);
}
}
catch ( ClassNotFoundException | SQLException ex) {
JOptionPane.showMessageDialog(null, "Unknown Error!! Data cannot be displayed!" + ex);
}
}
I am calling this method like this :
private void codeKeyReleased(java.awt.event.KeyEvent evt)
{
showtitle();
}
After inserting 1000 data my query is running very slow. Is my procedure not good? Is there some fatal mistake? What should I do?
You're doing more than just executing a query in your method.
You're also creating the JDBC connection, which is probably a much more expensive operation.
Trying creating the JDBC connection once and saving it somewhere in your application.
Then when the user runs your key-released event, just run your query and fetch the results.
It looks like your case doesn't really need the power of 'LIKE', maybe just use '=' instead? 'LIKE' is much mor powerful but may not be able to utilize indices, so you may end up performing a full table scan (see Use '=' or LIKE to compare strings in SQL? )
I am trying to write a function for this button. I want to be able to pass it a textfield value and be able to go into my database to retrieve some information.....
Can somebody explain to me what is going on and provide me a solution to this madness?
Thank you all xD
I keep running into this stupid problem:
ACTION1 createdoracle.jdbc.driver.T4CConnection#484845aa
Exception:java.sql.SQLSyntaxErrorException: ORA-00904: "ART": invalid identifier
Code:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
//CLASS TYPE
//LIST ALL OFFERED CLASSES AND REVENUE
try{
String classtype = jTextField1.getText().trim();
if(classtype.equals("")){
JOptionPane.showMessageDialog(this, "Sorry Wrong input.... Please try again....");
}
else if(classtype != ""){
try
{
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn=DriverManager.getConnection(
"jdbc:oracle:thin:#fourier.cs.iit.edu:1521:orcl",
"usr","pwd");
Statement stmt = conn.createStatement();
System.out.println("ACTION1 created"+conn+"\n\n");
String ct = jTextField1.getText().trim();
//String aa = "SELECT * FROM CLASS WHERE TYPE="+classtype;
//System.out.println(aa);
ResultSet rset = stmt.executeQuery("SELECT * FROM CLASS WHERE TYPE="+ct);
while (rset.next()) {
System.out.println(rset.getString("TITLE") + " ");
}
JOptionPane.showMessageDialog(this, "Class Type: "+classtype);
stmt.close();
conn.close();
System.out.println("Connection Closed");
}
catch(Exception sqle){
System.out.println("\nException:"+sqle);
}
}
}
catch(Exception e){
JOptionPane.showMessageDialog(this, "Please Retry input....", "Error", JOptionPane.ERROR_MESSAGE);
}
}
Let me guess ... does the ct String start with "ART" (or some variation)?
If so, the problem is that SQL requires quotes around string literals. Your query probably looks to Oracle something like this:
SELECT * FROM CLASS WHERE TYPE=Art of War
but it should look like
SELECT * FROM CLASS WHERE TYPE='Art of War'
There are two ways to fix this:
Assemble the query with quote characters around ct.
Write the query as "SELECT * FROM CLASS WHERE TYPE=?", use a PreparedStatement instead of a Statement and use the setString method to supply the parameter value.
If done properly, the second approach is both more secure and more efficient. (The problem with string-bashing the query and using Statement is that you are potentially making yourself vulnerable to SQL injection attacks.)
You're passing the value as part of the query, and the string concatenation you're doing makes the SQL into:
SELECT * FROM CLASS WHERE TYPE=ART
(where ART is the value of ct from the textfield) so it's trying to find a column on the table called ART. At an absolute minimum you need to quote the string:
ResultSet rset = stmt.executeQuery("SELECT * FROM CLASS WHERE TYPE='" + ct + "'");
But really don't do this; as #Andreas_D says you're leaving yourself open to SQL injection. Always use prepared statements and bind variables:
String sql = "SELECT * FROM CLASS WHERE TYPE=?";
PrepareStatement stmt = conn.prepareStatement(sql);
stmt.setString(1, ct);
ResultSet rset = stmt.executeQuery();