Inserting variables with SQL in Java - java

I'm writing a webpage that takes input from a form, sends it through cgi to a java file, inserts the input into a database through sql and then prints out the database. I'm having trouble inserting into the database using variables though, and I was wondering if anyone would be able to help me out.
String a1Insert = (String)form.get("a1");
String a2Insert = (String)form.get("a2");
This is where I get my variables form the form (just believe that it works, there's a bunch more back end but I've used this before and I know it's getting the variables correctly).
String dbURL = "jdbc:derby://blah.blahblah.ca:CSE2014;user=blah;password=blarg";
Connection conn = DriverManager.getConnection(dbURL);
Statement stmt = conn.createStatement();
stmt.executeUpdate("set schema course");
stmt.executeUpdate("INSERT INTO MEMBER VALUES (a1Insert, a2Insert)");
stmt.close();
This is where I try to insert into the databse. It give me the error:
Column 'A1INSERT' is either not in any table in the FROM list or appears within a join specification and is outside the scope of the join specification or appears in a HAVING clause and is not in the GROUP BY list. If this is a CREATE or ALTER TABLE statement then 'A1INSERT' is not a column in the target table.
If anyone has any ideas that would be lovely ^.^ Thanks

java.sql.Statement doesn't support parameters, switching to java.sql.PreparedStatement will allow you to set parameters. Replace the parameter names in your SQL with ?, and call the setter methods on the prepared statement to assign a value to each parameter. This will look something like
String sql = "INSERT INTO MEMBER VALUES (?, ?)";
PreparedStatement stmt = con.prepareStatement(sql);
stmt.setString(1, "a1");
stmt.setString(2, "a2");
stmt.executeUpdate();
That will execute the SQL
INSERT INTO MEMBER VALUES ('a1', 'a2')
Notice the parameter indexes start from 1, not 0. Also notice I didn't have to put quotes on the strings, the PreparedStatement did it for me.
Alternatively you could keep using Statement and create your SQL string in Java code, but that introduces the possibility of SQL injection attacks. Using PreparedStatement to set parameters avoids that issue by taking care of handling quotes for you; if it finds a quote in the parameter value it will escape it, so that it will not affect the SQL statement it is included in.
Oracle has a tutorial here.

Related

I need to set different target for different users by using the mysql query

I need to set different target for different users by using the mysql query. I have created the table with the name of Files18, this table has four columns (userid as varchar, team as varchar, department as varchar, Target as integer).
Now with the reference of UserId, I need to set the Target value.
Here is my query:
try{
String sql = "SELECT Target from Files18 where UserId= '"+text.getText()+"' ";
Connection con = DriverManager.getConnection("jdbc:mysql://193.168.2.251:3306/Transcription", "root", "root");
PreparedStatement pstm = con.prepareStatement(sql);
ResultSet Rs = pstm.executeQuery();
JT_Target = new JTextField(20);
JT_Target.setEnabled(false);
JT_Target.setFont(new Font("Tahoma", Font.BOLD, 15));
JT_Target.setBackground(Color.GRAY);
JT_Target.setText(String.valueOf(Rs.getInt("Target")));
}
catch(Exception ex){}
How can I do this?
You are not adding your created JTextField object to your GUI. You created an instance and set some properties (including the content), but you don't add it to your GUI by using the add() methods of your container like JFrame or JPanel.
Also, you must call the next() method on your result set to jump to the first row in the result set. After that you can use the get*() methods to read the data from the current row. With additional next() calls you get to the following rows until you reach the end of the result set.
You have a try-catch block which catches every exception but you don't do anything with it. When there are any errors you don't see them. Maybe you have an exception right now but because you don't do anything in your catch block you don't see it. Rewrite your error handling to display or generate helpful error messages.
Additionally, that is not how you use prepared statements. To use variables inside a prepared statements you first create a prepared statements with ? characters as placeholders for values in the query. The query should look like this:
SELECT Target from Files18 where UserId=?
When you have created your prepared statement you can use the set*() methods so insert the values for the query like this:
pstm.setInt(1, Integer.parseInt(text.getText()));

Java PreparedStatement SQL syntax error [duplicate]

This question already has answers here:
Java PreparedStatement complaining about SQL syntax on execute()
(6 answers)
Closed 6 years ago.
This is a really weird error that only started appearing today. When I use a prepared statement with ? for parameters, I get an error, but when I use it without parameters, it works just fine.
Here is the error-causing code:
String table = "files";
Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASS);
PreparedStatement prep = conn.prepareStatement("SELECT * FROM ?");
prep.setString(1, table);
ResultSet rs = prep.executeQuery();
while(rs.next()) {
System.out.println(rs.getString("file_name"));
}
This produces the following error:
Exception in thread "main" 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 ''files'' at line 1
Also, changing it to the following works just fine:
String table = "files";
Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASS);
PreparedStatement prep = conn.prepareStatement("SELECT * FROM " + table);
ResultSet rs = prep.executeQuery();
while(rs.next()) {
System.out.println(rs.getString("file_name"));
}
This doesn't seem to be making a whole lot of sense. Any ideas?
Tried it on another table and got more weired results.
This works and logs the admin in correctly:
String sql = "SELECT * FROM " + ADMIN_AUTH_TABLE + " WHERE " + column + " = '" + hashedPassword + "'";
PreparedStatement prepared = connection.prepareStatement(sql);
The following doesn't cause errors, but returns a message saying that the password entered is incorrect (it's correct - I double triple checked).
String sql = "SELECT * FROM " + ADMIN_AUTH_TABLE + " WHERE ? = ?";
PreparedStatement prepared = connection.prepareStatement(sql);
prepared.setString(1, column);
prepared.setString(2, hashedPassword);
Got it: use ? for values.
Also, the answer here helped.
Bind parameters cannot be used for identifiers in the SQL statement. Only values can supplied through bind placeholders.
This will work:
SELECT foo FROM bar WHERE id = ?
This will not work, because the table name is an identifier
SELECT foo FROM ? WHERE id = 2
You can't supply a column name, because column names are also identifiers.
A statement like this will run, but it may not do what you think it does.
SELECT ? AS foo FROM bar WHERE ? = 0
If we supply values of 'foo' for both placeholders, the query will actually be equivalent to a query containing two string literals:
SELECT 'foo' AS foo FROM bar WHERE 'foo' = 0
MySQL will run that statement, because it's a valid statement (if the table bar exists and we have privileges on it.) That query will return every row in bar (because the predicate in the WHERE clause evaluates to TRUE, independent of the contents of the table.. And we get returned the constant string foo.
It doesn't matter one whit that the string foo happens to match the name of column in our table.
This restriction has to do with how the SQL optimizer operates. We don't need to delve into all the details of the steps (briefly: parsing tokens, performing syntax check, performing semantics check, determining query plan, and then the actual execution of the query plan.)
So here's the short story: The values for bind parameters are supplied too late in that process. They are not supplied until that final step, the execution of the query plan.
The optimizer needs to know which tables and columns are being referenced at earlier stages... for the semantics check, and for developing a query plan. The tables and columns have to be identified to the optimizer. Bind placeholders are "unknowns" at the time the table names and column names are needed.
(That short story isn't entirely accurate; don't take all of that as gospel. But it does explain the reason that bind parameters can't be used for identifiers, like table names and column names.)
tl;dr
Given the particular statement you're running, the only value that can be passed in as a bind parameter would be the "hashedPassword" value. Everything else in that statement has to be in the SQL string.
For example, something like this would work:
String sqltext = "SELECT * FROM mytable WHERE mycolumn = ?";
PreparedStatement prepared = connection.prepareStatement(sqltext);
prepared.setString(1, hashedPassword);
To make other parts of the SQL statement "dynamic" (like the table name and column name) you'd have to handle that in the Java code (using string concatenation.) The contents of that string would need to end up like the contents of the sqltext string (in my example) when it's passed to the prepareStatement method.
The parameters of PreparedStatement should be applied only in parameters that can be used in conditional clauses. The table name is not the case here.
If you have a select where the table name can be applied in the conditional clause you can do it, otherwise you can not.

Getting Incorrect return in java accessing sql database

This is the code im using in java to query the database
connect = DriverManager.getConnection (url, "user", "pass");
state = connect.createStatement();
String meetID = "SELECT GamerTag FROM backup";
ResultSet rs = state.executeQuery(meetID);
while(rs.next()){
System.out.println(rs.toString());
}
Im not getting the values of the row in the database im getting this instead
com.mysql.jdbc.JDBC4ResultSet#108137c9
You're printing the result of the toString method of the Recordset object, which appears to print out the object's name and hashcode.
Instead, try to print the value of a column. Perhaps using getString:
System.out.println(rs.getString("GamerTag"));
The documentation for Java's recordset looks confusing, you might be better off searching for examples.
What do you expect rs.toString() should do it will just print the hash of the resultsetObject if you want to get the column values you should do this way
while(rs.next()){
System.out.println(rs.getString("yourFirstColumnName")+" "+
rs.getString("yourSecondColumnName")+" "+
rs.getString("yourThirdColumnName"));
}
Really you should use PreparedStatement. In your case though you are not using any parameterizedQuery but One of the major benefits of using PreparedStatement is better performance. PreparedStatement gets pre compiled.
In database and there access plan is also cached in database, which allows database to execute parametric query written using prepared statement much faster than normal query because it has less work to do. You should always try to use PreparedStatement.
So you can do something like this
String query = "SELECT GamerTag FROM backup"
PreparedStatement st =connect.prepareStatement("query");
ResultSet rs = st.executeQuery();

Inserting data into Multiple tables

String insert1 = "INSERT INTO Table1(Col1, col2, col3)"
+ "VALUES(?,?,?)";
String insert2 = "INSERT INTO Table2(Colx, coly)"
+ "VALUES(?,?)";
Connection conn = aConn;
PreparedStatement ps = null;
try {
ps = conn.prepareStatement(insert1);
// ps.addBatch(insert2);
I'm trying to Insert Data into multiple tables at a time, and it seems like addBatch(String sql) is not defined for PreparedStatement.
Is there any alternate way?
First of all, a PreparedStatement is used to cache a single SQL statement. This has the advantage that the driver/database might optimize the statement since it is expecting many of them and since it is a parameterized statement. If you want to use it for two different SQL statements you need two PreparedStatements.
In order to add rows to the statement you need to set your parameters using set*(1,...), set*(2,...), set*(3,...), etc. and then call addBatch() (no arguments!). Finally you submit the batch of statements using executeBatch().

String truncation when using PreparedStatement and SetString with SQL Server

I'm trying to use PreparedStatement and setString to insert data into a TEXT field of a SQL Server DB. The statement is something like this:
PreparedStatement p = con.prepareStatement("insert into comments(comments) VALUES (?)");
p.setString(1, comment);
The insert is working correctly but being truncated after 200-some characters. An error is not thrown. I can't find reference to this being the case anywhere else. It's definitely coming from the Java side, I've tested longer inserts into the SQL db directly.
Ideas? Is there a way I could convert the string to a different data type maybe?

Categories