Adding new values to mysql database no longer possible? - java

Hi guys please consider the code below. I was using it to add new values to my table(booking) in mysql database(seat_booking).
Variables include String(id,cname,ctype,event_name) and int(seatsno).I also call a function EventName() in this code and, trust me guys it works perfectly and I am able to derive the event name from the another table(events) but the only problem arises in this method.
Guys my project is to make a seat booking GUI app so this code does work when I used it to add new events for the "Admin" mode but doesn't work here ,i.e., when I need it to store the booking values for a particular customer. Please help guys. I would really appreciate it.
private void newbookbtnActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
try {
Class.forName("java.sql.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost/seat_booking","root","<mypassword>");
Statement stmt = con.createStatement();
String query = "SELECT * FROM booking";
ResultSet rs = stmt.executeQuery(query);
String cname = tfcname.getText();
int seatsno = Integer.parseInt(tfseatsno.getText());
String evtname = EventName();
String ctype = "Normal Customer"; long bookid = getID();
String id = Long.toString(bookid);
String query1="insert into booking values('"+ id +"','"+ cname +"','"+ ctype +"','"+evtname+"',"+ seatsno+");";
stmt.executeUpdate(query1);
JOptionPane.showMessageDialog(null, "Booking successfull!");
stmt.close();
con.close();
}
catch (Exception e)
{
JOptionPane.showMessageDialog(null,"Error encountered while booking new event!");
}
}
I have tried putting the e.Stacktrace(); statement in the application and I ran it the following was the resulting output for error:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 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 's Track Events Warm-up,1)' at line 1
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.Util.getInstance(Util.java:386)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1053)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4120)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4052)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2503)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2664)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2788)
at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1816)
at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1730)
at CustomerNewBook.newbookbtnActionPerformed(CustomerNewBook.java:256)
at CustomerNewBook.access$100(CustomerNewBook.java:16)
at CustomerNewBook$2.actionPerformed(CustomerNewBook.java:110)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
...

You use the wrong driver class. correct is:
Class.forName("com.mysql.jdbc.Driver");
java.sql.Driver is only an Interface. For more informations see the javadoc
BTW: Learn about prepared Statements to prevent sqlinjection
Do not supress error Messages. Atleast log them or put it into the message Dialog:
catch (Exception e)
{
e.printStacktrace();
JOptionPane.showMessageDialog(null,"Error encountered while booking new event!"+e.getMessage());
}

Update 2 (for this comment) :
Check the error,
You have an error in your SQL syntax ... near s Track Events Warm-up,1) ...
The problem is with the Strings that you are passing. Make sure any of your variables (id, cname, ctype, evtname) doesn't contain single qoutes(') or any other escape characters which may disturb the query.
This problem would easily be solved by using Prepared Statements. Try,
String query1 = "INSERT INTO `booking` VALUES(?, ?, ?, ?, ?)";
PreparedStatement stmt = con.prepareStatement(query1);
stmt.setString(1, id); //1 specifies the first parameter in the query
stmt.setString(2, cname);
stmt.setString(3, ctype);
stmt.setString(4, evtname);
stmt.setInt(5, seatsno); //use setInt() to parse ints
stmt.executeUpdate();
Update (for this comment):
In your catch block, comment the JOptionPane line and add the following,
catch (Exception e){
e.printStackTrace();
// JOptionPane.showMessageDialog(null, ...);
}
then run your application once again and update the question with the error output.
Original answer :
If you are using jdbc:mysql you need the MySQL connector.
Download it from mysql-connector-java-8.0.12,
Add the mysql-connector-java-8.0.12.jar to your project.
Change the driver class,
Class.forName("com.mysql.jdbc.Driver");
Clean and build (Optional but recommended).

Related

How to inject a SQL command to drop a table in java

My java code for SQL Query is
String sqlSt="INSERT INTO users(id,name,place) values ("+null+",'"+request.getParameter("name")+"','"+request.getParameter("place")+"');";
I have tried out
name= a'); DROP TABLE users; --
as well as
place =a'); DROP TABLE users; --
but it returns an Ecxeption as below
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 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 'DROP TABLE users; --','chennai')' at line 1
Note: when i tried the same in mysql command line. It worked!!!! i don't know what happens in jdbc
The real problem is actually JDBC, it only allows one sql if you dont tell it otherwise.
Look at this question for more info:
Multiple queries executed in java in single statement
But also i would try this instead, name =
a',''); DROP TABLE users; --
Since you specificed 3 columns in your insert:
(id,name,place)
You need to provide 3 values for the sql to be valid, not just 2.
Also you can sent the text null, sending a java null value is not necessary and i am not even sure how that works. I think this might be better:
String sqlSt="INSERT INTO users(id,name,place) values (null,'"+request.getParameter("name")+"','"+request.getParameter("place")+"');";
Instead of null, use an empty string ''
String sqlSt = "INSERT INTO users(id, name, place) values ('', '" + request.getParameter("name") + "', '" + request.getParameter("place") + "');";
It's better to use prepared statements to avoid confusion.
String sqlSt = "INSERT INTO users(id, name, place) values ('', ?, ?)";
PreparedStatement ps = null;
try {
ps = connection.prepareStatement(query);
ps.setString(1, request.getParameter("name"));
ps.setString(2, request.getParameter("place"));
ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
ps.close();
}
The real problem is with your Query. It is better to use a PreparedStatement for executing a query.
Your Code should be :
String sqlSt="INSERT INTO users(id,name,place) values (?,?,?)";
PreparedStatement pstmt = null;
try{
pstmt = dbConnection.prepareStatement(sqlSt);
pstmt.setString(1,null);
pstmt.setString(2,request.getParameter("name"));
pstmt.setString(3,request.getParameter("place"));
pstmt.executeUpdate();
}catch (Exception e) {
e.printStackTrace();
} finally {
pstmt.close();
}
If you don't want to use a PreparedStatement, just remove last ; from your query.
So your query will be :
String sqlSt="INSERT INTO users(id,name,place) values ("+null+",'"+request.getParameter("name")+"','"+request.getParameter("place")+"')";

Java/JDBC/SQLite/BLOB - Major Flaw With Blob

I am having a difficult time with just updating the data within my SQLite Database. I have tried using a BinaryStream however no luck. So I then decided, screw it. No need to update the Blob, if I delete any code related to the BLOB (even in the SQL Statement) the Update statement doesn't execute (properly). Prior to adding the BLOB everything worked fine. Now I just can't seem to understand why I cannot update my database any longer. If I take out the BLOB, program will say "Employee has successfully added to the database" however, when I look at my database, all information is the same. I can insert, search and delete them methods are fine, just updating just doesn't seem to be working for me. I am running out of ideas on what to do, could someone possibly help me? Even if it's not updating the BLOB, at this rate I'll take anything. Update or no update.
Code -
updateEmployee.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
Connection connection = null;
PreparedStatement pst = null;
try {
Class.forName("org.sqlite.JDBC");
connection = DriverManager.getConnection("jdbc:sqlite:employeeDatabase.sqlite");
connection.setAutoCommit(false);
String sql = "UPDATE employees SET ID =?, Name=?, Gender=?, DOB=?, Address=?, Postcode=?, NIN=?, JobTitle=?, StartDate=?, Salary=?, Email=?, Images=? WHERE ID=?";
pst = connection.prepareStatement(sql);
pst.setInt(1,Integer.parseInt(idTextField.getText()));
pst.setString(2, nameTextField.getText());
pst.setString(3, genderTextField.getText());
pst.setString(4, dobTextField.getText());
pst.setString(5, addressTextField.getText());
pst.setString(6, postcodeTextField.getText());
pst.setString(7, ninTextField.getText());
pst.setString(8, jobtitleTextField.getText());
pst.setString(9, startdateTextField.getText());
pst.setString(10, salaryTextField.getText());
pst.setString(11, emailTextField.getText());
pst.setBytes(12, readFile(s));
pst.executeUpdate();
System.out.println("EmployeeAdded");
JOptionPane.showMessageDialog(null, "Employee has successfully added to the database");
connection.commit();
pst.close();
connection.close();
}
catch ( Exception e1 ) {
JOptionPane.showMessageDialog(null, "Uh oh! Something went wrong!");
}
}
});
Thank you.
Sorted the issue.
It was with the line-
String sql = "UPDATE employees SET ID =?, Name=?, Gender=?, DOB=?, Address=?, Postcode=?, NIN=?, JobTitle=?, StartDate=?, Salary=?, Email=?, Images=? WHERE ID=?";
I needed to add pst.setInt(12,Integer.parseInt(idTextField.getText())); for WHERE ID=?.
Never happened to me before though, alas I'll take it.
Your command text has 13 parameter placeholders (?) but you are only defining 12 parameters. You are missing the last one, which should presumably be the same value as the first one ("ID").

Java MySQL with prepared statement says parameter index out of range

I've looked on here before, but none of the answers helped me out!
I have the following code:
public void addSerialToDb(String serial) {
System.out.println(serial);
try{
System.out.println(getMaxInt());
}catch (Exception e){
e.printStackTrace();
}
String serialV2 = ""+serial;
try{
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection(url, user, password);
pst = con.prepareStatement("INSERT INTO blogdata.serials" + "VALUES(?, ?)");
pst.setInt(1, getMaxInt());
pst.setString(2, serialV2);
pst.executeUpdate();
}catch (Exception e) {
e.printStackTrace();
}
closeDataBase();
}
In my database scheme, there are 2 columns, first one is integer (id) and second one is a VARCHAR(45) (serial). But still I get the following error:
java.sql.SQLException: Parameter index out of range (2 > number of parameters, which is 0).
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:964)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:897)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:886)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:860)
at com.mysql.jdbc.PreparedStatement.checkBounds(PreparedStatement.java:3321)
at com.mysql.jdbc.PreparedStatement.setInternal(PreparedStatement.java:3306)
at com.mysql.jdbc.PreparedStatement.setString(PreparedStatement.java:4021)
at DataBase.SerialDataBase.addSerialToDb(SerialDataBase.java:41)
I used this method on another program, but since switched to IntelliJ it stopped working.
Thanks in advance!
EDIT:
I forgot to mention, I'm using Java 1.8, the mySql connector 5.1.40 and running MySql 5.7.15
According to your comment getMaxInt() method, the problems is because of prepare statement object. It's being updated in getMaxInt() method and parameters not match error occurred. I think it's program logic error and you just need to change this program logic. I also recommend to not concat the String if it's not needed.
Below is just ok.
pst = con.prepareStatement("INSERT INTO blogdata.serials (column1,column2) VALUES (?,?)";
Try using the insert statement like this:
"INSERT INTO blogdata.serials (column1,column2) VALUES (?,?)";

mysql prepared statement java

I'm working with a prepared statement I've generated, and I'm getting a syntax error on the statement thrown by java. Yet when i copy and paste the toString of the PS into phpmyadmin for the database, it executes flawlessly. any idea's what could be wrong, i'm fairly stumped?
edit: changed to ps.executeUpdate(query); still doesn't work.
public int addOrder(Order order){
int rs=false;
try {
String query = "INSERT INTO `orders`(`orderNumber`, `productNumber`, `quantity`, `orderer`, `assembler`, "
+ "`meshType`, `beadType`, `beadCount`, `notes`, `dateCompleted`, `dateSubmitted`, `isComplete`) "
+"VALUES (?,?,?,?,?,?,?,?,?,?,?,?)";
PreparedStatement ps = con.prepareStatement(query);
ps.setString(1, order.getOrderNumber());
ps.setInt(2, order.getProductNumber());
ps.setInt(3, order.getQuantity());
ps.setString(4, order.getOrderer());
ps.setString(5, order.getAssembler());
ps.setString(6, order.getMesh());
ps.setString(7, order.getBeadType());
ps.setInt(8, order.getBeadCount());
ps.setString(9, order.getNotes());
ps.setLong(10, order.getDateCompleted().getTime());
ps.setLong(11, order.getDateSubmitted().getTime());
ps.setBoolean(12, order.getIsComplete());
System.out.println(ps.toString());
rs = ps.executeUpdate(query);
}
catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return rs;
}
the error message i get, preceded by the ps.toString() from addOrder. and like i said, if i copy paste the relevant part of the toString into phpmyadmin and execute it works fine. any ideas of what i'm doing wrong?
com.mysql.jdbc.JDBC4PreparedStatement#40378309: INSERT INTO
`orders`(`orderNumber`, `productNumber`, `quantity`, `orderer`,
`assembler`, `meshType`, `beadType`, `beadCount`, `notes`,
`dateCompleted`, `dateSubmitted`, `isComplete`) VALUES
('',251,1,'Mark','','Other','LBB',150,'this is a
test',1357249393009,1357249393010,0)
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 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
'?,?,?,?,?,?,?,?,?,?,?,?)' at line 1 at
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown
Source) at
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown
Source) at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411) at
com.mysql.jdbc.Util.getInstance(Util.java:386) at
com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1053) at
com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4096) at
com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4028) at
com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2490) at
com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2651) at
com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2728) at
com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2678) at
com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:894) at
com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:732) at
cbs.business.internalorders.Database.addOrder(Database.java:232) at
cbs.business.internalorders.IOGui$1.widgetSelected(IOGui.java:205) at
org.eclipse.swt.widgets.TypedListener.handleEvent(Unknown Source) at
org.eclipse.swt.widgets.EventTable.sendEvent(Unknown Source) at
org.eclipse.swt.widgets.Widget.sendEvent(Unknown Source) at
org.eclipse.swt.widgets.Display.runDeferredEvents(Unknown Source) at
org.eclipse.swt.widgets.Display.readAndDispatch(Unknown Source) at
cbs.business.internalorders.IOGui.(IOGui.java:218) at
cbs.business.internalorders.InternalOrders.main(InternalOrders.java:15)
#TheCapn's deleted answer is almost correct. Change executeQuery(query) to executeUpdate(), without the parameter.
If you put query in it, it will execute twice. With your case, you should not put query in it. All you need is like this;
ps.executeUpdate(query); <-- remove 'query'
//should be like this
ps.executeUpdate();
executeQuery(); //Generally this use for select statement. The output will be in Resultset.
executeUpdate(); //Generally this use for insert, update, delete and drop table.
execute(); //If you don't know which method to be used for executing your SQL statements, you can use this.
String query = "INSERT INTO `orders`(`orderNumber`, `productNumber`, `quantity`, `orderer`, `assembler`, "
+ "`meshType`, `beadType`, `beadCount`, `notes`, `dateCompleted`, `dateSubmitted`, `isComplete`) "
+"VALUES (?,?,?,?,?,?,?,?,?,?,?,?)";
should read
String query = "INSERT INTO orders(orderNumber, productNumber, quantity, orderer, assembler, "
+ "meshType, beadType, beadCount, notes, dateCompleted, dateSubmitted, isComplete) "
+"VALUES (?,?,?,?,?,?,?,?,?,?,?,?)";
i.e. no quotes.
I think the error could be from the data type conversion. Can you try without using parameters and setting the values directly? I had similar issues in ADO.NET before.
I finally found my solution, For some reason it didn't like my setStrings so I set it the long way and got it to work. thank you!

Resultset not open

I get following error on Result set
java.sql.SQLException: ResultSet not open. Verify that autocommit is OFF.
at org.apache.derby.client.am.SQLExceptionFactory40.getSQLException(Unknown Source)
at org.apache.derby.client.am.SqlException.getSQLException(Unknown Source)
at org.apache.derby.client.am.ResultSet.next(Unknown Source)
public ResultSet insertDb(int Id,String firstName,String lastName,String title) throws SQLException{
try {
try {
Class.forName(driver);
con = DriverManager.getConnection(connectionURL);
} catch (SQLException ex) {
Logger.getLogger(Connect.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(Connect.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println(con.getAutoCommit());
statement = con.createStatement() ;
res = statement.executeQuery("SELECT * FROM CUSTOMER") ;
con.setAutoCommit(false);
System.out.println(con.getAutoCommit());
while(res.next()){
if(res.getString("ID").equalsIgnoreCase(Integer.toString(Id))){
UNIQUE = false;
error= "Duplicate Entry Found Please Enter New Data";
throw new SQLException("Duplicate info<br>ID " + Id );
}
}
// IF value to be added IS UNIQUE
if(UNIQUE){
String qry1= "insert into CUSTOMER(ID, FIRSTNAME,LASTNAME,TITLE) values(?,?,?,?)";
stm = con.prepareStatement(qry1);
String ID=Integer.toString(Id);
stm.setString(1, ID);
stm.setString(2, firstName);
stm.setString(3, lastName);
stm.setString(4, title);
stm.executeUpdate();
}
}
catch(Exception e){
String errorMessage = "Exception caught : ";
System.out.println(errorMessage + e.toString());
}finally{
if (con != null){
con.close();
}
}
return res;
}
Try moving the setAutoCommit() and getAutoCommit() to before you create and execute the statement. Changing it after you execute the statement may be invalidating the query.
The problem is that you have closed your query before reading your resultset. Closing the query, closes the resultset, hence why you get the "ResultSet not open" error. You should close the query right at the end, in a finally block:
i.e. con.setAutoCommit(false);
will close the query and along iwth it it closes the resultset also.
Not strictly related, but your code probably doesn't do what you expect. This kind of read-modify-write code doesn't work well when there are multiple concurrent invocations.
If you imagine two invocations running though the code, it becomes clear that sometimes, depending on the execution order, BOTH invocations could reach the insert statement.
In addition, selecting from a table without using a WHERE clause is not generally useful. In this case you select '*', then iterate over all the results to see if "ID" == Id. The database is much much better at that than java is. You should add a where clause. (Note that this still won't solve the above problem)
Its also generally a bad idea to 'select *' from any table. Just pick the columns that you need. This will 'fail fast' if the schema changes and the columns that you need are no longer available, and will allow the database optimiser to do the 'right thing' about its disk accesses.
Finally, if its just a numeric ID that you are looking to assign, its normal practice to use 'autonumber' for these, rather than get the program to pick them. Different databases call them different things, so you might also know them as IDENTITY, or have to use a sequence.
In case it helps anyone down the line, I had the same error with Derby 10.5.1.1 that turned out to be a bug in the driver itself that would appear some times and not others depending on the underlying data. Upgrading the driver to a newer version (10.8.2.2) resolved the problem.

Categories

Resources