This is my latest attempt to read a text file into a Netbeans Derby database. The file contains 5 rows with each row containing 7 items delineated by commas. The program runs without any errors but the database is not updated at all. I would appreciate any help in fixing this code.
<% Connection connection = null;
PreparedStatement ps = null;
String urlanddatabasename = "jdbc:derby://localhost:1527/ProgramName
String userName = "root";
String password = "root";
Class.forName("org.apache.derby.jdbc.ClientDriver");
connection = DriverManager.getConnection(urlanddatabasename,userName,password);
try{
String fileName = saveFile;
File file = new File(fileName);
Scanner inputStream = new Scanner(file);
String[] array = new String[7];
Statement statement = connection.createStatement();
while(inputStream.hasNext()){//reads from the file until there are no items left
String data = inputStream.next();
array = data.split(",");
String reportidString = array[0];
String coursenameString = array[1];
String tardiesString = array[2];
String absencesString = array[3];
String totalgradeString = array[4];
String teachernameString = array[5];
String schoolnameString = array[6];
statement.executeUpdate("INSERT INTO report(reportid, coursename, tardies, absences, totalgrade, teachername, schoolname) values(reportidString, coursenameString,tardiesString, absencesString, totalgradeString, teachernameString, teachernameString, schoolnameString)");
}
inputStream.close();
}catch(FileNotFoundException e){e.printStackTrace();}
%>
It seems that you are using this code inside a JSP scriptlet. This is very bad style. Especially for code without any relation to the view representation.
So the first thing you should do, is to create an ordinary Java class and put that code inside. Then you will remark that Class.forName() throws a checked exception (ClassNotFoundException) and some other parts like DriverManager.getConnection(), connection.createStatement() and statement.executeUpdate() throw SQLException. You shouldn't let the servlet container catch these exceptions.
Then write a simple main() method to check if your code is working or even better a JUnit test.
You declared a PreparedStatement variable but never used it. Instead later you used a simple Statement. The first one fits better here. So use something like that:
ps = connection.prepareStatement("INSERT INTO "
+ "report(reportid, coursename, tardies, absences, totalgrade, teachername, schoolname) "
+ "values(?, ?, ?, ?, ?, ?, ?)");
Use the ? as a placeholder for the actual values.
Then later you set the values. Beware that the prepared statement index begins at 1. After the execution of all SQL inserts, you should commit the transaction. In case of an exception use abort().
while(inputStream.hasNext()){//reads from the file until there are no items left
// ...
ps.setString(1, reportidString);
ps.setString(2, coursenameString);
// ...
ps.executeUpdate();
}
connection.commit();
Afterwards you should clean up and free the ressources. The best place is in a finally of a try block:
} finally {
try {
ps.close();
} catch(SQLException e) {
e.printStackTrace();
}
try {
connection.close();
} catch(SQLException e) {
e.printStackTrace();
}
}
Some further considerations:
If you really want to use plain JSP, then make use of the Front Controller pattern. So every request goes to the front controller servlet. There you decide what kind of action to execute and collect the data for the view. In the end forward to a JSP to create the view. Inside the JSP you should not use any scriptlets.
Consider to use a MVC framework like Struts or Spring MVC. But the current standard is Java Server Faces which is more component based.
Use a connection pool for the database connection.
Use logging instead of System.out.println() or e.printStackTrace()
To efficiently insert larger files into the database use batch inserts.
There is a system procedure in Derby that may help:
http://db.apache.org/derby/docs/10.11/ref/rrefimportproc.html
http://db.apache.org/derby/docs/10.11/adminguide/cadminimport16245.html
Related
say I've got a JSON like this:
{"name": "tom", "id":1, "clothes":[{"shirt":"yellow"},{"shoes":black},.......]}
I'm trying to insert it, as is, into a column in a mysql DB using Java.
void insertVal(JsonObject json){
Connection conn = null;
try {
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/Orders?user=root", "root", "1234");
Statement st = conn.createStatement();
StringBuilder values = new StringBuilder("(");
for (String key : json.keySet()){
if (key.equals("clothes")){
//do something to deal with this array
break;
}
values.append(json.get(key)).append(",");
}
values.append(")");
String insert = "INSERT INTO ORDERS VALUES " + values;
st.executeUpdate(insert);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
This code works fine up to clothes key. So far, I've tried using JSON OBJECT and JSON MERGE but the format doesn't quite match, and I'd rather not parse right now.
So, is it possible to add clothes or do I have to parse it somehow? if so, what format would work best?
Thanks a lot
To all those concerned: The problem was the " string. mysql, and probably SQL in general, don't handle these well. There are two options. The first, and less recommended:
String parsed = json.get(key).toString().replace("\"", "");
Then, insert normally.
The second, much more recommended - use PreparedStatement. This way, you can write an insert/update query without minding the escape characters. Example, after i've inserted 'null' values for the clothes column:
PreparedStatement ps = conn.prepareStatement("UPDATE ORDERS set CLOTHES = ? WHERE ID = ?");
ps.setString(1, clothes); // clothes - get(key).toString()
ps.setInt(2, count); // count - counts which iteration we are
ps.executeUpdate();
I hope anyone in the future finds this useful.
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.
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 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.
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"