MySQLSyntaxErrorException while trying to update database - java

I'm doing an app for school project and I came across this error I've tried to figure it out but I can't seem to fix it.
Let me explain the problem first, basically I'm trying to update previously created user. Initially the profile has only username and a password. I want the user to be able to add whatever details he wishes to later on once he has created his own profile.
I have one class which has the database connectivity and update Profile method. The other class is a jFrame where user can input some data into textfields and the intention is that it will be inserted into fields for existing profile within the database (Initially those fields are declared as null).
Below you can see my DBConnect class which contain the Login method and UpdateProfile method. In the login method I'm creating a profile object which holds all the variables and methods such as getUsername, getPassword etc.
public class DBConnect {
private Connection dbConnection;
public Profile profile;
public DBConnect() {
try {
dbConnection = DriverManager.getConnection("jdbc:mysql://localhost:3306/prototype?user=root");
} catch (Exception ex) {
System.out.println("Connection failed :" + ex);
}
}
public void Login() {
profile = new Profile(LoginWindow.usernameField.getText(), LoginWindow.passwordField.getText());
Statement userQuery = null;
try {
//Look for the user with valid username and password
userQuery = dbConnection.createStatement();
ResultSet rs = userQuery.executeQuery("Select * FROM Profile WHERE pName = \"" + profile.getUsername() + "\" and password = \"" + profile.getPassword() + "\"");
if (rs.next()) {
profile.isLoggedin(true);
} else {
profile.isLoggedin(false);
}
} catch (SQLException ex) {
profile.isLoggedin(false);
System.out.println(ex);
} finally {
try {
if (userQuery != null) {
userQuery.close();
}
} catch (SQLException ex) {
System.out.println("Failed to close login query");
}
}
}
public void updateProfile(String _height, String _weight, String _goalWeight, String _age) {
Statement updateQuery = null;
try {
updateQuery = dbConnection.createStatement();
updateQuery.executeUpdate("UPDATE Profile SET height='" + _height + "',weight='" + _weight + "',goalWeight='" + _goalWeight + "',age='" + _age + "' WHERE pName =" + profile.getUsername());
} catch (SQLException ex) {
System.out.println(ex);
} finally {
try {
if (updateQuery != null) {
updateQuery.close();
}
} catch (SQLException ex) {
System.out.println("Failed to close updateCustomer query");
}
}
}
}
I'm trying to update some of the fields that were empty with the Update Profile method and to get the profile that I want to update I wrote "WHERE pName =" + profile.getUsername());" in order to retrieve the record of the user.
Finally in the EditProfile jFrame I wrote this method to pass on the parameters for the updateProfile methods.
private void saveButtonActionPerformed(java.awt.event.ActionEvent evt) {
LoginWindow.dbc.updateProfile(heightTextField.getText(), weightTextField.getText(), goalWeightTextField.getText(), ageTextField.getText());
}
Everything compiles but I'm having mySQLSyntaxError which is:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'Admin' in 'where clause'
The database is not updated and I don't know how to fix it.
My assumptions is that there is a problem with "WHERE pName =" + profile.getUsername());" in updateProfile declaration. The "Admin" is the result of profile.getUsername(); and its the actual username of currently logged in user.
Please help.

You have a little syntax error: Your line
updateQuery.executeUpdate("UPDATE Profile SET height='" + _height + "',weight='" + _weight + "',goalWeight='" + _goalWeight + "',age='" + _age + "' WHERE pName =" + profile.getUsername());
should read
updateQuery.executeUpdate("UPDATE Profile SET height='" + _height + "',weight='" + _weight + "',goalWeight='" + _goalWeight + "',age='" + _age + "' WHERE pName ='" + profile.getUsername()) + "'";
(You need to enclose the pName parameter with single quotes.)
...and you really need to start using PreparedStatement as others also suggested.

that exactly the problem. try that:
ResultSet rs = userQuery.executeQuery("Select * FROM Profile WHERE pName = '" + profile.getUsername() + "' and password = '" + profile.getPassword() + "' ");

Related

MySQL checking if a entry is set

Im trying to check if a entry is set, so for example in a row with: user, password, birth
I check if in column user f.e. "mxrlin" is
For that im using that code in my Main Class:
if(!mySQL.isSet(tableName, "houseNumber", houseNumberStr)){
System.out.println(house.getHouseNumber() + " not set yet");
inserts.add(new BetterMySQL.KeyValue("houseNumber", houseNumberStr));
mySQL.insertEntry(tableName, inserts);
}else {
System.out.println(house.getHouseNumber() + " set -> updating");
mySQL.update(tableName, inserts, "houseNumber", houseNumberStr);
}
And the mySQL.isSet() method looks like this:
public boolean isSet(String tableName, String key, String value){
Check.checkNotEmpty(tableName);
Check.checkNotEmpty(key);
Check.checkNotEmpty(value);
ResultSet resultSet = MySQL.getResultSetPrepareStatement(connection, "SELECT * FROM " + tableName + " WHERE ?=?", Arrays.asList(key, value));
try {
if(resultSet.next()){
return resultSet.getObject(value) != null;
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return false;
}
But with this code it always debugs me "house.getHouseNumber() + " not set yet", so the Class doesnt find the entry that is set
You can't bind a parameter to a column name. The key in this case will be treated as a string literal in SQL.
Assuming a method call like this:
mySQL.isSet("houses", "houseNumber", "2335")
this code:
ResultSet resultSet = MySQL.getResultSetPrepareStatement(connection, "SELECT * FROM " + tableName + " WHERE ?=?", Arrays.asList(key, value));
Will generate a SQL statement equivalent to
SELECT * FROM houses WHERE 'houseNumber'='2335'
Of course, the string 'houseNumber' will never equal the string '2335', so no results will be returned.
You'll need to substitute key into the SQL string, just like tableName already is:
ResultSet resultSet = MySQL.getResultSetPrepareStatement(connection, "SELECT * FROM " + tableName + " WHERE " + key + "=?", Arrays.asList(value));

Database link name expected when executing update for oracle database

I'm relatively new to coding and Java. I have an assignment where we build a GUI using JavaFX that interfaces with an oracle database with relevant data to be entered into our GUI product. In our GUI we are supposed to have an Update button which function is to update/alter a specific row in the database after making changes to the data in the GUI textfields/comboboxes. For my update action I have the button linked to I get the error java.sql.SQLSyntaxErrorException: ORA-01729: database link name expected. I have searched online for answers but I don't fully understand what this means and how to solve this issue. I set up my connection in the beginning of my code and included static Connection con; Statement stmt; earlier in my code. Any ideas/help would be appreciated
My code is below:
void updateEmp() {
try {
String updateQuery = "UPDATE employees SET firstname = '"
+ tfFirstName.getText() + "', lastname = '"
+ tfLastName.getText() + "', salary = "
+ tfSalary.getText() + ", title = '"
+ jobTitlesCbo.getValue() + "'";
/*if (getDeptNum(deptTitlesCbo.getValue()) > 0
&& getDeptNum(deptTitlesCbo.getValue()) < 6) {
updateQuery = updateQuery + ", departmentid = '"
+ getDeptNum(deptTitlesCbo.getValue()) + "'";
}*/
updateQuery = updateQuery + " WHERE employeeid = " + tfEmpID;
stmt.executeUpdate(updateQuery);
} catch (Exception e) {
System.out.println("Error: " + e.toString());
e.printStackTrace();
}
}

JAVA & SQL database save changes

I am working on Java GUI application which connects to SQL database on localhost (I use XAMPP). When I change some entry, for example Age, I click on "Save changes", it is saved and changes are done in SQL database, but when I click on ">" or "<" to view next or previous person and then go back to the person, where I did changes, every entry is without changes in its initial state. But when I close the application and reopen it, all the changes which I made are done. This is part of the code where is mistake, I think. Thank you.
private void jButtonSaveChangesActionPerformed(java.awt.event.ActionEvent evt) {
try {
Statement stmt = con.createStatement();
try {
String query1 = "UPDATE list1 SET " +
"name ='" + jTextFieldName.getText() + "', " +
"surname ='" + jTextFieldSurname.getText() + "', " +
"age ='" + jTextFieldAge.getText() + "' " +
"WHERE ID = " + jLabelActualID.getText();
stmt.executeUpdate(query1);
} catch (Exception e) {
System.err.println(e);
}
} catch (Exception e) {
System.err.println(e);
}
}
Picture of application:
You are not closing, which can be done more safe and automatically with try-with-resources.
This means a commit might not have happened yet. There is an autocommit setting too.
String query1 = "UPDATE list1 SET " +
"name = ?, " +
"surname = ?, " +
"age = ? " +
"WHERE ID = ?";
try (PreparedStatement stmt = con.prepareStatement(query1)) { // Closes stmt.
stmt.setString(1, jTextFieldName.getText());
stmt.setString(2, jTextFieldSurname.getText());
stmt.setInt(3, Integer.parseInt(jTextFieldAge.getText()));
stmt.setString(4, jLabelActualID.getText());
int updateCount = stmt.executeUpdate();
} catch (SQLException | NumberFormatException e) {
System.err.println(e);
}
The same may hold (or may not hold) for the SQL connection.
Also one should use a PreparedStatement for security (SQL injection) and type safeness / escaping of backslash, quote in strings. As you see it is even more readable.
Another case is a second application accessing the database: it can use its own cache, thereby be a bit outdated.

SQL query join issue in Java program

I have a class that contains methods that connect to a database, run a query, and assigns data from the database into variables.
The purpose of this Java program is to scan a database that houses information on security threats for client's servers. When the query is run it should return selected data fields from 2 tables (target_stats and attack_stats) upon reading that the number of attacks (target_stats.num_attacks) is above 0.
I can successfully retrieve data from the target table but I get null values from the attacker table and I know that the field is not null in the database.
My question: can anyone detect an error, most likely a logical one, in my query that is causing the unfavorable results? I am a beginner programmer and fairly new to SQL.
Also, I am in the process of learning setters and getters in this program, all of the retrieved data is to be used in another class but I am testing and learning with just the target field for now. Perhaps that is causing an issue?
UPDATE I rant he query in MySQL query browser and get the same unfavorable result, so the problem is just in my query logic. I have done some research in queries and joins but must still be lacking suitable knowledge.
My code (hopefully I post it correctly in format):
public class Database {
String details = null;
int threat_level = 0;
ResultSet rslt = null;
private String target2;
Connection con;
public void createConnection() {
//Establish a connection
try {
con = DriverManager.getConnection("sensitiveInformation");
} catch (SQLException e) {
e.printStackTrace();
}
System.out.println("Database connected");
}
public ResultSet getData() {
String query = "SELECT target_stats.server_id, target_stats.target, target_stats.threat_level, target_stats.client_id, attack_stats.attacker, attack_stats.num_this_attack " +
" FROM target_stats " +
" LEFT OUTER JOIN attack_stats " +
" ON target_stats.target = attack_stats.target " +
" WHERE target_stats.num_attacks > '0' " +
" AND target_stats.interval_id>'2'";
Statement stmt = null;
try {
stmt = con.createStatement();
} catch (SQLException e) {
e.printStackTrace();
}
try {
rslt = stmt.executeQuery(query);
} catch (SQLException e) {
e.printStackTrace();
}
return rslt;
}
public void process() {
try {
String server_id = rslt.getString("server_id");
target2 = rslt.getString("target");
threat_level = rslt.getInt("threat_level");
int client_id = rslt.getInt("client_id");
String attacker = rslt.getString("attacker");
String num_this_attack = rslt.getString("num_this_attack");
details = "Target IP: " + target2 + " Server ID: " + server_id + " Client ID: " + client_id + " Threat Level: " + threat_level + " Attacker IP: " + attacker + " Number of attacks: " + num_this_attack;
System.out.println(details);
} catch (SQLException e) {
e.printStackTrace();
}
}
public String getTraget2() {
return target2;
}
}
Update: I should mention that I have a while loop in another class that properly reads through each record.
Update 2: Here is the main class, I am not concerned with the GUI elements right now:
public class MainDisplay extends JFrame {
static Toolkit tk = Toolkit.getDefaultToolkit();
static int Width = (int)tk.getScreenSize().getWidth();
static int Height = (int)tk.getScreenSize().getHeight();
public static JFrame frame = new JFrame();
public static JLayeredPane lpane = new JLayeredPane();
public static String target;
public static void main (String[] args) {
new MainDisplay();
}
public MainDisplay() {
frame.setPreferredSize(new Dimension(Width, Height));
frame.setLocation(0,0);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setUndecorated(true);
//NoRisk Run = new NoRisk();
//Run.NoThreat();
ThreatPanel Run = new ThreatPanel();
Database Data = new Database();
//Create Connection to Database and run query
Data.createConnection();
Data.getData();
try {
while(Data.rslt.next()){
Data.process();
Run.TargetServer = Data.getTraget2();
System.out.print(Data.getTraget2()); //for testing purposes
Run.ShowThreats();
try {
Thread.sleep(1000*10); // sleeps for ten seconds
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} catch (SQLException e) {
e.printStackTrace();
}
//Run.ShowThreats();
frame.setLayout(new BorderLayout());
frame.add(lpane, BorderLayout.CENTER);
lpane.setBounds(0,0, Width, Height);
frame.pack();
frame.setVisible(true);
}
}
Did you try to execute the same query in database? You mentioned it should return some results but did you try it in database before putting in the codes? If the database is not returning the desirable result, we will look into the query statement, for example instead of left outer join you might have to use inner join.
The field in attacker table may be not null, but when you have LEFT OUTER JOIN - you will have null values in a query when there is no corresponding data in attack_stats table - please check that.
The query looks ok - try with LEFT INNER JOIN - then you will have no rows visible where there are no corresponding data in attack_stats table.
Pat, Can you post your main method, from where you are calling this code. Also you should iterate over resultset to move the cursors.
while(rslt.next())
{
String server_id = rslt.getString("server_id");
target2 = rslt.getString("target");
threat_level = rslt.getInt("threat_level");
int client_id = rslt.getInt("client_id");
String attacker = rslt.getString("attacker");
String num_this_attack = rslt.getString("num_this_attack");
details = "Target IP: " + target2 + " Server ID: " + server_id + " Client ID: " + client_id + " Threat Level: " + threat_level + " Attacker IP: " + attacker + " Number of attacks: " + num_this_attack;
System.out.println(details);
}

Suddenly getting SQL Exceptions when using sql variables in statements

I have a SQL query, consisting of different statements (this is a simplified version, which also triggers the error) :
private static String getActiveKeyEventsSql =
"SET #report_model_id = 2; " +
"SELECT MAX(report_ts) AS report_ts " +
"FROM `pulse_data`.`key_event_reports` " +
"WHERE report_model_id = #report_model_id ";
I am trying to call that statement from inside my Java Application:
public static void main(String[] args) throws Exception {
MySQLLayer _db = new MySQLLayer();
Connection _conn = null;
try {
_conn = _db.getConnection();
PreparedStatement getActiveKeyEventsStmt = _conn.prepareStatement(getActiveKeyEventsSql);
ResultSet rs = getActiveKeyEventsStmt.executeQuery();
while (rs.next()) {
LOG.info(rs.getLong("report_ts"));
}
} catch (SQLException e) {
LOG.error("COULD NOT GET MAX REPORT.", e);
} finally {
try {
if (_conn != null && !_conn.isClosed()) {
_conn.close();
}
} catch (SQLException e) {
LOG.info("COULD NOT CLOSE CONNECTION.", e);
}
}
}
But it triggers the following error:
java.sql.SQLException: ResultSet is from UPDATE. No Data.
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1073)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:987)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:982)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:927)
at com.mysql.jdbc.ResultSetImpl.next(ResultSetImpl.java:6870)
at com.stockpulse.stockstorm.sentiment.JavaTest.main(JavaTest.java:36)
In other places of my application, this schema works just fine. When I copy this statement to the MySQL console, it works just fine.
Here is the String to init the DB:
config.setJdbcUrl(
"jdbc:mysql://" + cred.getHOST() + "/" + cred.getDB()
+ "?allowMultiQueries=true&characterEncoding=utf-8&useUnicode=true&rewriteBatchedStatements=true&relaxAutoCommit=true"
);
Why is JDBC behaving this way out of the sudden?
Try breaking your statement into
a = "SET #report_model_id = 2; ";
b = "SELECT MAX(report_ts) AS report_ts " +
"FROM `pulse_data`.`key_event_reports` " +
"WHERE report_model_id = #report_model_id ";
And do PreparedStatement.addBatch() for each.

Categories