I was executing my code on IntelliJ and it shows an error in this code, I don't understand why? I just have 3 columns and 1 row in my database and I want to update each column with new values( VARCHAR() ), but keeps showing this error.
print("\n>>");//print is a function which does System.out.print("");
String url= in.escinput();//escinput() is a function which does ob.nextLine()
print(">>");
String user=in.escinput();
print(">>");
String pass=in.escinput();
String nurl="",nuser="",npass="";
println("Uploading updates...");
try {
Connection c = DriverManager.getConnection(url, user, password);
Statement s=c.createStatement();
PreparedStatement ps;
ps=c.prepareStatement("Update conn set url="+url);
ps=c.prepareStatement("Update conn set user="+user);
ps=c.prepareStatement("Update conn set password="+pass);
ps.executeUpdate();
ResultSet rs=s.executeQuery("SELECT * from conn");
while (rs.next())
{
nurl=(rs.getString("url"));
nuser=(rs.getString("user"));
npass=(rs.getString("password"));
}
if ((nurl.equals(url))||(nuser.equals(user))||(npass.equals(pass)))
{
if ((nurl.equals(url))&&(nuser.equals(user))&&(npass.equals(pass)))
println("Update was sucessful");
else
{
if (!(nurl.equals(url)))
println("URL was not updated");
if (!(nuser.equals(user)))
println("USER was not updated");
if (!(npass.equals(pass)))
println("PASSWORD was not updated");
}
}
c.close();
}
catch (Exception e)
{
in.conerror();
String h=in.escinput();
if (h.equals("printST"))
e.printStackTrace();
}
In this line
PreparedStatement ps;
ps=c.prepareStatement("Update conn set url="+url);
ps=c.prepareStatement("Update conn set user="+user);
ps=c.prepareStatement("Update conn set password="+pass);
ps.executeUpdate();
IntelliJ shows this error
java.sql.SQLSyntaxErrorException: Unknown column 'passs' in 'field list'
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1092)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1040)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1350)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:1025)
at JA_2_0.main(JA_2_0.java:256)
I don't understand what's happening, please help
Since I don’t see passs (with three s characters) in your code, I’m guessing the pass variable contains something like ,passs in it, quite possibly as a deliberate measure to test your proper use of PreparedStatement.
Don’t invent your own sanitizing of input
I assume in.escinput() is meant to sanitize a string so it’s safe to place into an SQL statement. However, no programmer should be doing that themselves. PreparedStatement already does that, and it will always do it better than any application programmer can:
String pass = ob.nextLine();
// ...
ps = c.prepareStatement("Update conn set password=?");
ps.setString(1, pass);
Repeated assignments are destructive, not additive
The assignment operator (=) does not add to a variable. When you assign three values to ps, you are just replacing the value of ps. The old value is discarded. There is no secret mechanism remembering or adding the assignments into a batch operation.
You probably just want a single update statement:
String url = ob.nextLine();
String user = ob.nextLine();
String pass = ob.nextLine();
// ...
ps = c.prepareStatement("Update conn set url=?, user=?, password=?");
ps.setString(1, url);
ps.setString(2, user);
ps.setString(3, pass);
ps.executeUpdate();
ps.close();
You could also do it as three statements, though that doesn’t have any benefit, and in fact would be slower:
ps = c.prepareStatement("Update conn set url=?");
ps.setString(1, url);
ps.executeUpdate();
ps.close();
ps = c.prepareStatement("Update conn set user=?");
ps.setString(1, user);
ps.executeUpdate();
ps.close();
ps = c.prepareStatement("Update conn set password=?");
ps.setString(1, pass);
ps.executeUpdate();
ps.close();
Method calls don’t need to be encased in parentheses
Finally, you don’t need parentheses around every expression. Generally, parentheses are only needed when you need to override the natural precedence of operators. While they don’t make a difference in how the program behaves, they do make your code harder to read and harder to maintain.
Meaning, you can change this:
nurl=(rs.getString("url"));
nuser=(rs.getString("user"));
npass=(rs.getString("password"));
to this:
nurl=rs.getString("url");
nuser=rs.getString("user");
npass=rs.getString("password");
And you can change this:
if ((nurl.equals(url))||(nuser.equals(user))||(npass.equals(pass)))
{
if ((nurl.equals(url))&&(nuser.equals(user))&&(npass.equals(pass)))
to this:
if (nurl.equals(url) || nuser.equals(user) || npass.equals(pass))
{
if (nurl.equals(url) && nuser.equals(user) && npass.equals(pass))
And you can change this:
if (!(nurl.equals(url)))
println("URL was not updated");
if (!(nuser.equals(user)))
println("USER was not updated");
if (!(npass.equals(pass)))
println("PASSWORD was not updated");
to this:
if (!nurl.equals(url))
println("URL was not updated");
if (!nuser.equals(user))
println("USER was not updated");
if (!npass.equals(pass))
println("PASSWORD was not updated");
The period (.) has extremely high precedence, so an expression that uses it is treated as a single value in almost every circumstance.
Related
int rs = stmt.executeUpdate("INSERT INTO Leden VALUES (null,"+u+","+p+",'1')");
I'm getting the error
java.sql.SQLException: Unknown column '(the U variable)' in 'field list';
I know for sure it is 100% the "" but i can't seem to find it where it goes wrong
any help is appreciated!
This is my whole method (I want to learn how to do it with a prepared statement)
public static void connectionDB(String u, String p, String f){
{
try {
String username = "/////////";
String password = "///////";
String url = "///////////////";
Connection connection = DriverManager.getConnection(url, username, password);
Statement stmt = connection.createStatement();
int rs = stmt.executeUpdate("INSERT INTO Leden VALUES (null,'"+u+"','"+p+"','1')");
} catch (SQLException e) {
e.printStackTrace();
}
System.out.println("Database connected!");
}
}
It should be like
int rs = stmt.executeUpdate("INSERT INTO Leden VALUES (null,'"+u+"','"+p+"','1')");
Update:-
You can also look into prepared statements because
Prepared statements are much faster when you have to run the same statement multiple times, with different data. Thats because SQL will validate the query only once, whereas if you just use a statement it will validate the query each time.
Assuming fields are A,B,C,D;
A is int and remains are strings
String insertTableSQL = "INSERT INTO Leden"
+ "(A,B,C,D) VALUES"
+ "(?,?,?,?)";
preparedStatement.setInt(1, 11);
preparedStatement.setString(2, "Hello");
preparedStatement.setString(3, "this");
preparedStatement.setString(4, "OP");]
preparedStatement .executeUpdate();
It should be
int rs = stmt.executeUpdate("INSERT INTO Leden VALUES (null,'"+u+"','"+p+"','1')'");
The issue is, that " is used in SQL for objects like columns or tables, whereas ' is used for strings. So in +u+, which seems to not exists in context of your query.
Your query itself should therefore look something like (given, that +u+ and +p+ are strings.
INSERT INTO Leden VALUES (null,'+u+','+p+','1')
If you need to have " inside your columns, it would read like
INSERT INTO Leden VALUES (null,'"+u+"','"+p+"','1')
Also I would recommend to specify the columns you are inserting to so it looks similar to:
INSERT INTO "Leden" ("col1", "col2", "col3", "col4") VALUES (null,'+u+','+p+','1')
This will prevent your query from failing when extending table definition by another column.
Also using prepared statements could be a good idea here, as it helps you preventing from e.g. SQL injections.
I am trying to add two strings on two separate columns columns of my database using Java but I'm not sure what I am doing wrong. The code I am using
try{
Connection conn = DriverManager.getConnection(
"jdbc:ucanaccess://C:/Users/nevik/Desktop/databaseJava/Employee.accdb");
Statement st = conn.createStatement();
String sql = "Select * from Table2";
ResultSet rs = st.executeQuery(sql);
rs.updateString("user", user);
rs.updateString("pass", pass);
rs.updateRow();
}
catch(SQLException ex){
System.err.println("Error: "+ ex);
}
The first column on my database is user and the next one is pass. I am using UCanAccess in order to access my database.
This is how you normally update a row in java:
String query = "update Table2 set user = ?, pass= ?";
PreparedStatement preparedStmt = conn.prepareStatement(query);
preparedStmt.setInt (1, user);
preparedStmt.setString(2, pass);
// execute the java preparedstatement
preparedStmt.executeUpdate();
First of, you've not updated the position of the current cursor in the ResultSet, which means that it's pointing to nothing...
You could use...
if (rs.next()) {
rs.updateString("user", user);
rs.updateString("pass", pass);
rs.updateRow();
}
But this assumes two things...
You have a database that supports updating values in the ResultSet and
You want to update the existing values.
To insert a value into the database, you should be using the INSERT command, for example...
try(Connection conn = DriverManager.getConnection(
"jdbc:ucanaccess://C:/Users/nevik/Desktop/databaseJava/Employee.accdb")) {
try (PreparedStatement stmt = conn.prepareStatement("INSERT into Table2 (user, pass) VALUES (?, ?)") {
stmt.setString(1, user);
stmt.setString(2, pass);
int rowsUpdated = stmt.executeUpdate();
}
}
catch(SQLException ex){
System.err.println("Error: "+ ex);
}
You might like to take some time to go over a basic SQL tutorial and the JDBC(TM) Database Access trail
As a side note...
You should not be storing passwords in Strings, you should keep them in char arrays and
You should not be storing passwords in the database without encrypting them in some way
#guevarak12
About the original question (how to use updatable ResultSet):
your code is wrong, you have to move the cursor in the right position.
In particular, if you are inserting a new row you have to call rs.moveToInsertRow(); before rs.updateString("user", user).
If you are updating an existent row, you have to move the cursor calling rs.next() and so reach the row to update.
Also you have to create the Statement in a different way:
Statement st =conn.createStatement( ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
See junit examples in the UCanAccess source distribution, class net.ucanaccess.test.CrudTest.
All other comments seem to be correct.
I was updating password in an oracle databse using a java servlet like this
Connection con;
PreparedStatement ps,ps1;
ResultSet rs;
try{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
}
catch (ClassNotFoundException e)
{
System.out.println("Drivers Not Found");
}
try{
con=DriverManager.getConnection("jdbc:odbc:SharedCryptography", "fyp", "fyp");
}catch(SQLException e1)
{
}
String query="UPDATE tbGroup SET GPassword='"+mypassword+"' where GName='"+GroupNamee+"' and OEmail='"+OwnerId+"'";
java.sql.Statement stmt = con.createStatement();
stmt.executeUpdate(query);
But it gives java.sql.SQLException: [Oracle][ODBC][Ora]ORA-01756: quoted string not properly terminated
Am i doing something wrong in it?Please help
You should absolutely avoid string concatenation in SQL statements. You will get in all kind of security and stability problems. Your problem is simply be resolved by using a prepared statement:
String sql="UPDATE tbGroup SET GPassword=? where GName=? and OEmail=?";
PreparedStatement ps = con.prepareStatement(sql);
ps.setString(1, myPassword);
ps.setString(2, groupName);
ps.setString(3, ownerId);
ps.executeUpdate();
If you do this, no "'" or "%" or "_" or " in your parameters will cause any problems. Alternatively you can try to escape your characters, but why bother - the PS method is not only more robust and easier to read, it is often also more performant.
For a general description of the security problems, see: https://www.owasp.org/index.php/SQL_injection
One of your variables (probably password) has a quote or semi colon in it. Since you build up your query via String concatenation, you are vulnerable to SQL injection attacks. It looks like you accidentally attacked yourself via injection. If you had a properly maliciously formatted variables you could have done quite a bit of damage to your database.
Please use Parameterized queries
PreparedStatement stmt = con.prepareStatement("UPDATE tbGroup SET GPassword= ? where GName= ? and OEmail=?" )
stmt.setString(1, mypassword);
...
stmt.executeUpdate();
See this for more details
https://www.owasp.org/index.php/Preventing_SQL_Injection_in_Java
Please don't suggest me to use InternalFrame or Dialogs. I can't start the project from beginning.
Theme: I'm building a GUI program to display mark-sheet. I've taken 3 JFrames & 1 simple class...
Frame1.java
It's having 1 JTextField to enter roll_no. & 2 buttons to feedData in DB & showResult. feedData button calls Frame2 & showResult button calls Frame3.
Frame2.java
For feeding data have several JTextFields & Buttons that transfer content to mySQL DB.
Frame3.java
is a result window that fetches content from DB.
Support.java
Contains static variables & getter-setter methods for them
.....
.....//contains in Support.java
public boolean add() {
query = "Insert into table1 (enroll,Sname,Fname,sub1,sub2,sub3,sub4,sub5 )values(?,?,?,?,?)";
try {
PreparedStatement psmt = conn.prepareStatement(query);
psmt.setString(1, enroll);
psmt.setString(2, Sname);
psmt.setString(3, Fname);
psmt.setInt(4, sub1);
psmt.setInt(5, sub2);
psmt.setInt(6, sub3);
psmt.setInt(7, sub4);
psmt.setInt(8, sub5);
int y = 0;
y = psmt.executeUpdate();
if (y == 0) {
return false;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
add() is called on pressing save button in Frame2.java . . . If catch block is executing, why println(query) printing NULL
Based on some of your question tags and responses in the comments to other answers and on the question itself, I'm presuming that somewhere in your code, you intend to call
Class.forName("com.mysql.jdbc.Driver").newInstance();
conn = DriverManager.getConnection(url, username, password);
This is not happening before your add() method is called. In order to fix it, I'd recommend this (bulk of code borrowed from Vivek bhatnagar's answer):
try {
conn = DriverManager.getConnection(url, username, password);
PreparedStatement pstmt = conn.prepareStatement("INSERT INTO `table`
(pid,tid,rid,tspend,description) VALUE
(?,?,?,?,?)");
pstmt.setString(1, pid );
pstmt.setString(2, tid);
pstmt.setString(3, rid);
pstmt.setInt(4, tspent);
pstmt.setString(5,des );
pstmt.executeUpdate();
} catch (Exception e) {
// whatever you want to do to handle the exception
} finally {
// close your connection
}
If you're on Java 7, set up like this:
try (Connection conn = DriverManager.getConnection(url, username, password)) {
try (PreparedStatement pstmt = conn.prepareStatement(/*sql here*/)) {
// Your code here
} catch (SQLException sqle) {
// handle exceptions from the statement
}
} catch (SQLException outerSqlEx) {
// handle exceptions from connecting
}
How could I tell what your problem was (general help for NullPointerException)?
NullPointerException is only thrown when you try to call a method on a null variable (and at a few other specific times, as noted in the API documentation). The easy way to locate a NullPointerException is to look for the line the stack trace indicates, and then look for the dots on the line. There's only two lines in your try block that can throw a NullPointerException.
Statement stmt = conn.createStatement();
// could be here ----^
and
y = stmt.executeUpdate(query);
// or --^
So let's look at the dots. The first one will throw when conn is null. The second one will throw when stmt is null. In your original code, which you've now edited in response to the other answers, you set the value of query after you called conn.createStatement();. Since query was still null in your catch block, we know that it hadn't yet been set, and thus it must be the first one, so conn is null at that point in the program.
Furthermore, since the API Documentation for createStatement
implies that it will either return a valid Connection object or throw an SQLException, we can be pretty sure that stmt will never be null when executeUpdate is called.
In your try block, you are calling a method that is possible to throw an exception before setting the variable in question:
Statement stmt = conn.createStatement();
query = "Insert into table1 (enroll,Sname,Fname,sub1,sub2,sub3,sub4,sub5 )values('" + getEnroll() + "','" + getSname() + "','"+getFname()+"',"+getSub1()+","+getSub2()+","+getSub3()+","+getSub4()+","+getSub5()+")";
Therefore, if your code fails on the conn.createStatement() line, it will enter the catch block without the query variable being initialized.
You can fix this simply by switching the order of the statements, or by putting the query line outside and before the try/catch blocks.
Adding to what #Southpaw answered :
you can use something like this also :
PreparedStatement pstmt = con.prepareStatement("INSERT INTO `table`
(pid,tid,rid,tspend,description) VALUE
(?,?,?,?,?)");
pstmt.setString(1, pid );
pstmt.setString(2, tid);
pstmt.setString(3, rid);
pstmt.setInt(4, tspent);
pstmt.setString(5,des );
pstmt.executeUpdate();
Kindly Note its benefits:
1."Query is rewritten and compiled by the database server"
If you don't use a prepared statement, the database server will have to parse, and compute an execution plan for the statement each time you run it. If you find that you'll run the same statement multiple times (with different parameters) then its worth preparing the statement once and reusing that prepared statement. If you are querying the database adhoc then there is probably little benefit to this.
2."Protected against SQL injection"
This is an advantage you almost always want hence a good reason to use a PreparedStatement everytime. Its a consequence of having to parameterize the query but it does make running it a lot safer. The only time I can think of that this would not be useful is if you were allowing adhoc database queries; You might simply use the Statement object if you were prototyping the application and its quicker for you, or if the query contains no parameters.
I have created a database connection with SQLite using JDBC in Java. My SQL statements execute properly, but sometimes I get the following error while I use conn.commit():
java.sql.SQLException: SQL logic error or missing database
Can anyone please help me how to avoid this type of problem. Is there a better approach of calling JDBC programs?
Class.forName("org.sqlite.JDBC");
conn = DriverManager.getConnection("jdbc:sqlite:/home/Data/database.db3");
conn.setAutoCommit(false);
String query = "Update Chits set BlockedForChit = 0 where ServerChitID = '" + serverChitId + "' AND ChitGatewayID = '" + chitGatewayId + "'";
Statement stmt = conn.createStatement();
try {
stmt.execute(query);
conn.commit();
stmt.close();
stmt = null;
}
Can your variables serverChitId & chitGatewayId contain characters that would corrupt the SQL? It is usually safer to use PreparedStatements:
PreparedStatement ps = conn.prepareStatement("Update Chits set BlockedForChit = 0 where ServerChitID = ? AND ChitGatewayID = ?");
ps.setString(1, serverChitId);
ps.setString(2, chitGatewayId);
ps.executeUpdate();
This way the JDBC driver is responsible for making sure the necessary escapes are made to the strings.
Try setting conn.setAutoCommit to true. Also you need to delete conn.commit();.
If you are doing this inside of a function, make your function synchronized.
It's even more better if you use PreparedStatement instead of Statement.
All this is happening because sometimes you are trying to connect and modify your database at a same time and since the last connection hasn't commited yet, it throws that exception. When you set it to autoCommit it will handle the flow by itself.(it was really painful for me cause it says nothing more, I read all of the org.sqlite.DB files to find this out)
Class.forName("org.sqlite.JDBC");
conn = DriverManager.getConnection("jdbc:sqlite:/home/Data/database.db3");
conn.setAutoCommit(true);
PreparedStatement ps = "Update Chits set BlockedForChit = 0 where ServerChitID = ? AND ChitGatewayID = ? ";
ps.setString(1, serverChitId);
ps.setString(2, chitGatewayId);
try {
ps.executeUpdate();
}