Read results from H2DB - java

I have a problem with reading the content of the rows in the database.
I want to show the information (in the console for the moment) about the employee with given position and name. I have built the path ,started the database in H2 but I am not sure I have used PreparedStatement right .
Table "MyTable" not found
I removed the try/catch to be more readable.
static public void Search (JButton a , JFormattedTextField name, JComboBox<String> b ) {
a.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e ) {
Connection con = null;
con = DriverManager.getConnection("jdbc:h2:tcp://localhost/~/test" + "sa" + "");
Statement stm = null;
String ime = name.getText();// reads the name
String poz = (String) b.getSelectedItem();// reads the position
Class.forName("org.h2.Driver");
String sql1 = String.format("SELECT * FROM RABOTNICI WHERE IME = '%s' OR POZICIA = '%s'", ime, poz);
PreparedStatement prstm = null;
prstm = con.prepareStatement(sql1);
ResultSet rs = null;
rs = prstm.executeQuery(sql1);
}
});
}

jdbc:h2:tcp:...
You are using TCP connection but not starting H2 TCP server like this:
http://www.h2database.com/html/tutorial.html#using_server
Normally H2 database is used as embedded without TCP server like this:
http://www.h2database.com/html/tutorial.html#connecting_using_jdbc
jdbc:h2:/path/to/dbfile

I think you had some sources of information and something went wrong down the way.
The way you created a preparedStatement, even if it's parsed correctly, is prone to SQL Injections.
You should first create the statement and only then inject the values.
String sql1 = "SELECT * FROM RABOTNICI WHERE IME = ? OR POZICIA = ?"
PreparedStatement prstm = con.prepareStatement(sql1);
prstm.setString(1, ime);
prstm.setString(2, poz);
Please consult this doc page for correct usage of PreparedStatements
Also, getConnection's argument looks a bit messed up.
con = DriverManager.getConnection("jdbc:h2:tcp://localhost/~/test" + "sa" + "");
The following line should appear before the connection creation.
Class.forName("org.h2.Driver");
I suggest using this tutorial for instruction regarding connection to H2 DB
And last, I'm not sure how do you get the error about "MyTable" its never mentioned in your code snippet.
My code quotes were not tested but I believe are clear enough to get the idea.

Related

Working on this Java project where I need to be able to delete data from the database on user's request

The query inside MySQL is working:
DELETE FROM f9.yoo
WHERE account_tags = '#8GGGJPUR9'
I can delete data inside MySQL, but the problem is whenever I try to remove the account_tags from my Java application, it throws an error:
java.sql.SQLSyntaxErrorException: 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 'DELETE FROM f9.yoo
WHERE account_tags = '#8GGGJPUR9'' at line 2
Here's my Java SQL query:
Statement statement = dbConnection.createStatement();
String sql = "SELECT * FROM "+databaseName+"."+tableName+";\n" +
"DELETE FROM "+databaseName+"."+tableName+"\n" +
"WHERE account_tags = '"+AccountTag+"';";
statement.executeQuery(sql);
The error isn't giving me much to work with, so I really have no idea what is wrong with the program.
Did you add the allowMultiQueries=true
If not then you can add that while you sending the connecting request to your database. So you need to append the allowMultiQueries=true in your to database URL.
Like this:
String dbUrl = "jdbc:mysql:///test?allowMultiQueries=true";
String sql = "DELETE FROM "+databaseName+"."+tableName+"\n" +
"WHERE account_tags = ?";
try (PreparedStatement statement = dbConnection.prepareStatement(sq)) {
statement.setString(1, AccountTag);
int updateCount = statement.executeUpdate();
System.out.printf("%s: %d records deleted.%n", tableName, updateCount);
}
The only thing used is the DELETE, for which one should use executeUpdate.
One definitely should use a PreparedStatement as many code checkers will give alarms otherwise. It escapes things like ', handles types of the arguments, and possible conversions, and especially is a security feature against SQL injection.
The System.out usage is bad style, better would be using a logger.
try-with-resources automatically closes the PreparedStatement even with a raised exception or break/return.
When doing both database operations, it seems better to use two (prepared) statements, as the first returns a ResultSet.
So:
String sql = SELECT * FROM "+databaseName+"."+tableName + "\n" +
"WHERE account_tags = ?";
try (PreparedStatement statement = dbConnection.prepareStatement(sq)) {
statement.setString(1, AccountTag);
try (ResultSet rs = statement.executeQuery()) {
...
}
}
Better to separate statements with an If condition :
String sql1="SELECT * FROM "+databaseName+"."+tableName;
String sql2="DELETE FROM "+databaseName+"."+tableName+" "+
"WHERE account_tags = '"+AccountTag+"';
statement.executeQuery(sql1);
statement.executeUpdate(sql2);

invalid column index error in java while fetching data from oracle 10g database. Cant figure out whats wrong

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.

multiple sql command

I'm trying to execute multiple sql commands, but it gives me "error in your SQL syntax;"
Db_Connection dbconn = new Db_Connection();
Connection myconnection = dbconn.Connection();
String sqlString = "SELECT DISTINCT std_id FROM std_crs WHERE crs_id ='222123'; "
+ "SELECT * FROM cplus_grades ;";
Statement myStatement = myconnection.createStatement();
boolean results = myStatement.execute(sqlString);
do {
if (results) {
ResultSet rs = myStatement.getResultSet();
while (rs.next()) {
}
rs.close();
}
results = myStatement.getMoreResults();
} while(results);
myStatement.close();
I did a small test with three JDBC drivers:
MS SQL: works, returns two result sets
MySQL: fails with a syntax error - that is what you are seeing
HSQLDB: runs, but returns only one result set.
So I guess it simply depends on the JDBC driver if this technique works. Maybe it works only in MS SQL JDBC.
UPDATE:
It also works with Postgres.
please
1. String dbUrl = "jdbc:mysql://yourDatabase?allowMultiQueries=true";
this should be your jdbc connection url

How to return result sets from Stored Procedure?

I created a Stored Procedure where I can fetch all my data that I inserted in my following textfields. How can I fetch all of this data by calling my Callable Statement? I think this is the easiest way than Batch Statement based on what I read. I only drag and drop this following components just a practice purposes.
Stored Procedure
CREATE PROCEDURE show_data(OUT FULLNAME VARCHAR(50), OUT ADDRESS VARCHAR(50))
PARAMETER STYLE JAVA
LANGUAGE JAVA
READS SQL DATA
DYNAMIC RESULT SETS 1
EXTERNAL NAME 'Frame.searchButton'
I used OUT parameter to retrieve values using getXXX() methods. I'm just little bit confuse since this is my first time to use Stored Procedure in derby.
GUI
After the user search the following record in Database. If the value exist it will print to the designated textfields.
SOURCE CODE
String searchRecord = searchTf.getText();
String searchQuery = "SELECT * FROM SAMPLEONLY";
ResultSet data[] = null;//Why should I use this array?
try (Connection myConn = DriverManager.getConnection(url, user, pass);
PreparedStatement myPs = myConn.prepareStatement(searchQuery);)
{
String addFullname = fullnameTf.getText();//first field
String addAddress = addressTf.getText();//second field
data[0] = myPs.executeQuery();
CallableStatement cs = myConn.prepareCall("{ call showData(?, ?)}");
cs.setString(1, addFullname);
cs.setString(2, addAddress);
boolean hasResults = cs.execute();
if (hasResults) {
ResultSet rs = cs.getResultSet();
while (rs.next()) {
String getFullname = rs.getString(1);//get the value
String getAddress = rs.getString(2);
fullnameTf.setText(getFullname);//set the text here
addressTf.setText(getAddress);
}//end of while
rs.close();//close the resultset
}//end of if
}//end of try
catch (SQLException e)
{
e.printStackTrace();
}
}//end of else
}
After I insert in Search textfields it throws me a error NullPointerExeption. I follow Derby Reference Manual so I can have a guide writing a proper Stored Procedure. This code is mine most of the part. Guide me if I missed something wrong. Feel free to comment thanks.

Derby Query is very slow

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? )

Categories

Resources