Struts2: Save SQL query in the database - java

In my Struts2 Java web application users are allowed to query the database. As an example, the user needs to get the employee details whose first name is equal to 'Charles'. Then s/he can select the report columns and criteria (firstname='Charles').
Once the user gives above inputs it need to save the relevant SQL query into the database.
e.g. SQL -> SELECT * FROM employee WHERE firstname='Charles'
Here is what I am trying in my action class.
try {
connection = DriverManager.getConnection(
SelectAction.getDatabase(), SelectAction.getUser(),
SelectAction.getPassword());
if (connection != null) {
System.out.println("Database connection established!");
stmt = connection.createStatement();
String sql = "INSERT INTO reports (report_id, sql) values ('" + reportId + "', '" + sqlQ + "');";
System.out.println("sql--->" + sql);
// Executing query
stmt.executeQuery(sql);
return SUCCESS;
} else {
System.out.println("----Failed to make connection!");
return ERROR;
}
} catch (SQLException e) {
System.out.println("Connection Failed!!");
e.printStackTrace();
return SUCCESS;
}
This is my insert query.
INSERT INTO reports (report_id, sql) values ('mynewreport', 'SELECT * FROM employee WHERE firstname='Charles'');
I am getting following error in my console.
ERROR: syntax error at or near "Charles"
I think here I am using a String so that the problem is with quotes('). I am using postgreSQL as database.
Any suggestions to solve this issue ?

Never use string concatenation of user supplied values to build a SQL statement.
Never use string concatenation of any non-integer values to build a SQL statement.
You will leave yourself open to SQL Injection attacks and/or SQL statement errors.
Hackers will love you for allowing them to steal all your data, and the nefarious ones will corrupt or delete all your data, while laughing maniacally at you on their way to the bank.
Use PreparedStatement and parameter markers.
String sql = "INSERT INTO reports (report_id, sql) values (?, ?)";
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, reportId);
stmt.setString(2, sqlQ);
stmt.executeUpdate();
}

Related

inserting new user object into JDBC through the servlet

Here is the code for my servlet which recieves username parameter from a registration form
String tusername=request.getParamater("un");
String dbURL="db.com";
String dbusername= "lc";
String dbpassword="lcpw";
Connection con=(Connection) DriverManager.getConnection(dbURL,dbusername,dbpassword);
Statement stmt= con.createStatement();
String query="SELECT * FROM users.username WHERE username=(tusername)";
ResultSet rs= stmt.executeQuery(query);
if(rs.next()==false){
//create new userobject with value of tusername
}
My question is how do I create a new user object with calue of tusername, would it be like so ?
if(rs.next()==false){
Statement stmt=con.createStatament();
String query="INSERT INTO user.username VALUE 'tusername'";
ResultSet rs= stmt.updateQuery(query);
}
I understand some of this might be archaic (such as not using a prepared statement) , I am just trying to better my understanding and I think I am having some small syntax issues, thanks :)
You should be using a NOT EXISTS query to do the insert, and also you should ideally be using a prepared statement:
String sql = "INSERT INTO user.username (username) ";
sql += "SELECT ? FROM dual WHERE NOT EXISTS (SELECT 1 FROM user.username WHERE username = ?)";
PreparedStatement ps = con.prepareStatement(sql);
ps.setString(1, tusername);
ps.setString(2, tusername);
int result = ps.executeUpdate();
if (result > 0) {
System.out.println("Inserted new user " + tusername + " into username table";
}
else {
System.out.println("User " + tusername + " already exists; no new record was inserted");
}
I don't know what your actual database is. The above should work out of the box for MySQL and Oracle. It might need to be modified slightly for other databases.
An alternative to the above query would be to just use your current insert, but make the username column a (unique) primary key. In that case, any attempt to insert a duplicate would fail at the database level, probably resulting in an exception in your Java code. This would also be a more database agnostic approach.

How to select data from table with parameter

Trying to get all the data in the row with the specified name string. Im getting a syntax error right now. myConn is declared in the constructor and name is a varchar in the database named organization. My error code is "Can not issue executeUpdate() or executeLargeUpdate() for SELECTs"
public void getOrgByName(String name){
try {
st = myConn.createStatement();
String query = "SELECT * FROM organization WHERE name = ?";
PreparedStatement preparedStmt = myConn.prepareStatement(query);
preparedStmt.setString(1, name);
preparedStmt.executeUpdate();
}catch(Exception e){
System.out.println("Cannot get org name" + e);
}
}
You’re performing a select query so you’ll need to use executeQuery i.e
Replace this:
preparedStmt.executeUpdate();
With this:
ResultSet rs = preparedStmt.executeQuery();

Accessing database with sqlite in Java

I am trying to access a database to then insert new data, but the code below gives me this output:
Opened database successfully
java.sql.SQLException: [SQLITE_ERROR] SQL error or missing database ()
The database is created in a different class, I still get this error whether the database has already been created or not.
What would be causing this error?
Statement stmt = null;
Connection c = null;
try {
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:src/test.db");
System.out.println("Opened database successfully");
stmt = c.createStatement();
String sql = "INSERT INTO table_one (id, name) VALUES (Null, 'Hayley');";
stmt.executeUpdate(sql);
System.out.println("Inserted records");
stmt.close();
c.close();
} catch ( Exception e ) {
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
System.exit(0);
}
System.out.println("Table created sucessfully");
How about not inserting the null value in the id column. It is of no use to insert null value. It might have generated the sql exception. Try INSERT INTO table_one (name) VALUES ('Hayley');.
I would suggest to use PreparedStatement instead of Statement because of the threat of SQL injection.
Sometimes, the particular sql exception can occur if the database name is not given. Have you tried writing the database name like INSERT INTO database_name.table_one (name) VALUES ('Hayley');.

How to insert two strings into my Access database from Java using UCanAccess?

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.

Inserting email in SQLite database using JDBC

I am trying to insert an email ID to a table in my SQLite3 Database. In my case it successfully creates the table but gives an error while inserting a record in it - "near "#gmail": syntax error". How can i resolve this ? Here is the code -
public void insertData(String emailId, double gtse, long receivedDate) throws ClassNotFoundException, SQLException{
Class.forName("org.sqlite.JDBC");
Connection connection = null;
try
{
// create a database connection
connection = DriverManager.getConnection("jdbc:sqlite:testdb.sqlite");
Statement statement = connection.createStatement();
statement.setQueryTimeout(30); // set timeout to 30 sec.
ResultSet result = statement.executeQuery("SELECT name FROM sqlite_master WHERE type='table' AND name='T1'");
if(!result.next()){
statement.executeUpdate("create table T1 (email TEXT, gtse REAL, receiveddate DATE)");
statement.executeUpdate("insert into T1 values(" + emailId + ", "+ gtse +", "+ receivedDate +")");
}
else{
}
}
catch(SQLException e)
{
// if the error message is "out of memory",
// it probably means no database file is found
System.err.println(e.getMessage());
}
finally
{
try
{
if(connection != null)
connection.close();
}
catch(SQLException e)
{
// connection close failed.
System.err.println(e);
}
}
}
Your core error is that for the insert query you are not enclosing the values to be inserted, in quotes. Your query, after construction, looks something like this:
insert into T1 values(whatever#gmail.com, emailtexthere, 04-07-2013)
When it should be something like this:
insert into T1 values('whatever#gmail.com', 'emailtexthere', '04-07-2013')
The SQL parser chokes while trying to parse your current query, because the syntax is incorrect. The solution to this problem is not simply to enclose the values in quotes though, but rather to use prepared statements. This is because the way you are constructing your query right now is vulnerable to SQL injection attacks. Here is an example of using a prepared statement:
PreparedStatement pStmt = conn.prepareStatement(
"INSERT INTO T1 VALUES(?, ?, ?)");
pStmt.setString(1, emailId);
pStmt.setString(2, gtse);
pStmt.setDate(3, receivedDate);
pStmt.execute();

Categories