I am working on a java project and I need to pull some values out of a database and turn them into variables the program will then use to make a billing statement. I can get the program to connect to the database just fine, and the mySQL statement to call the data I need is easy enough. I just can't seem to figure out how to then have it put each field returned in the resultset into a separate variable.
Shamelessly lifted from the jdbc tutorial
Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet srs = stmt.executeQuery(
"SELECT COF_NAME, PRICE FROM COFFEES");
while (srs.next()) {
String name = srs.getString("COF_NAME");
float price = srs.getFloat("PRICE");
System.out.println(name + " " + price);
}
You should review the JDBC tutorial, and this section answers your question.
Related
Im writing a java program and I have a SQL statement that currently is outputting wrong:
so the code is:
String sql = "SELECT Name from Users WHERE Name LIKE "+t;
and the Output is:
SELECT Name from Users WHERE Name LIKE David
But I need it to be with single quotes how can I add that to be like:
SELECT Name from Users WHERE Name LIKE 'David'
how can I add those quotes?
Many thanks for the help
This is a very common mistake. I'm guessing you are using Statement class to create your query and executing it.
I'd like to suggest that you use prepared statements. It'll since your issue and help you with further issues.
PreparedStatement ps = yourconn.prepareStatement("select name from users where name like ?");
ps.setString(1,yoursearchedusername);
ResultSet rs = ps.executeQuery();
This will add your quotes. Plus it will prevent from sql injection attacks in future.
Your current query will also cause issues of your actual query has ' or ? Or any other sql wild card. Prepared statement avoids all these issues and helps with performance by having the sql already compiled and stored at db layer (if enabled)
Use a prepared statement to prevent sql injections.
String searchedName = "cdaiga";
String sql = "SELECT Name from Users WHERE UPPER(Name) LIKE '%?%'";
PreparedStatement preparedStatement = dbConnection.prepareStatement(sql);
preparedStatement.setString(1, (searchedName!=null? searchedName.toUpper(): ""));
// execute the SQL stetement
preparedStatement .executeUpdate();
ResultSet rs = preparedStatement.executeQuery();
// print the results if any is returned
while (rs.next()) {
String name= rs.getString("Name");
System.out.println("name: " + name);
}
Note that a case insensitive search would be appropriate.
I have two method for update:
String query = "update mytable set name = 'new_value' where id ='20' ";
Connection conn;
PreparedStatement pState;
try {
conn = DriverManager.getConnection(dbUrl, "root", "2323");
pState = conn.prepareStatement(query);
pState.executeUpdate();
} catch (SQLException sql) {
sql.printStackTrace();
}
OR:
String query = "update mytable set name = ?" + "where id = ?";
Connection conn;
PreparedStatement pState;
int s;
try {
conn = DriverManager.getConnection(dbUrl, "root", "2323");
pState = conn.prepareStatement(query);
pState.setStringt(1, "new_value");
pState.setString(2, "20");
s = pState.executeUpdate(); // if s = 1 then update done successfully
} catch (SQLException sql) {
sql.printStackTrace();
}
Both methods update database record correctly, Which is better?
Second approach is good practice to avoid SQL Injection attacks.
And following is enough to construct query String, another + concatenation is not required.
String query = "update mytable set name = ? where id = ?";
I would say the second approach.
You aren't returning anything, so why create a result set and go down that path?
Edit:
Even after your comment, I would still use the second template. It's more flexible. Additionally, it's faster. The PreparedStatement is pre-compiled in the database which allows the database to execute a parametric query using the statement faster than a normal query. This won't happen if you use string concatenation (like in your first example).
See: http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html
Additionally, from that page:
The main feature of a PreparedStatement object is that, unlike a
Statement object, it is given a SQL statement when it is created. The
advantage to this is that in most cases, this SQL statement is sent to
the DBMS right away, where it is compiled. As a result, the
PreparedStatement object contains not just a SQL statement, but a SQL
statement that has been precompiled. This means that when the
PreparedStatement is executed, the DBMS can just run the
PreparedStatement SQL statement without having to compile it first.
Although PreparedStatement objects can be used for SQL statements with
no parameters, you probably use them most often for SQL statements
that take parameters. The advantage of using SQL statements that take
parameters is that you can use the same statement and supply it with
different values each time you execute it.
The second way is more faster if you use frequently the same query. Depends of the database vendor, the query is cached and the efficiency is higher than that using flat sentences. But all that depends on the implementation of the JDBC driver and the services provided by the database.
See more in Using Prepared Statements in the The Java Tutorials.
I am trying to use some query result to generate another query and execute the new query but that does not seem to work. The second query is not being executed. Can someone please tell me why? This is that part of the code.
Statment stmt = connnection.createStatement();
Statment stmt2 = connnection.createStatement();
ResultSet r = stmt.executeQuery("Select * from employees");
while (r.next()) {
String Str = "Select name from employees where employeeId = " + (r.getInt(3) + 1);
System.out.println(str);
query = stmt2.executeQuery(str);
System.out.println(query.getString(1));}
The right query seems to be generated, but just won't execute. Is there a reason why this is so. BTW "query" is declared as resultset.
Thanks
you can only have one statement executing at one moment in time against one database connection -- so you can either open another database connection and execute the second statement in the 2nd connection, or iterate through the resultset from first statement and store the employees database id's (e.g. in an array/collection) then close that statement and run the second one, this time retrieving the id's from the array/collection you saved them in.
This question already has answers here:
How can I get the SQL of a PreparedStatement?
(14 answers)
Closed 5 years ago.
I'm working with PreparedStatement with MySQL Server.
example:
String myQuery = "select id from user where name = ?";
PreparedStatement stmt = sqlConnection.prepareStatement(myQuery);
stmt.setString(1, "test");
stmt.executeQUery();
ResultSet rs = stmt.getResultSet();
How can I receive the full SQL query that is about to be executed on the MySQL Server?
It's not mandated by the JDBC spec, but several JDBC drivers let the toString of a PreparedStatement return sort-of the query that will be run, and MySQL's Connector/J happens to have this behavior (or at least it did a few years ago).
String myQuery = "select id from user where name = ?";
PreparedStatement stmt = sqlConnection.prepareStatement(myQuery);
stmt.setString(1, "test");
System.out.println(stmt); // May do what you want!
You cannot really get out the query that will be executed but there are logging APIs that will log database calls for you such as log4jdbc and p6spy.
You can't, as Java isn't responsible for constructing it. Prepared statements are supported within MySQL, so Java sends the actual parameterized SQL ("select id from user where name = ?") straight to MySQL along with the parameters
I can tell you what it is. If you're using MySQL 4.1 or newer with Connector/J 3.1 or newer, it will be something like:
PREPARE stmt FROM 'select id from user where name = ?'
SET #a = 'test'
EXECUTE stmt USING #a
This is because MySQL supports server-side prepared statements.
(More likely it uses the binary protocol, but this code is just to make a point)
Hi I implement the following code which fetch SQL from PreparedStatement . No need to use any jar and Driver .
public void printSqlStatement(PreparedStatement preparedStatement, String sql) throws SQLException{
String[] sqlArrya= new String[preparedStatement.getParameterMetaData().getParameterCount()];
try {
Pattern pattern = Pattern.compile("\\?");
Matcher matcher = pattern.matcher(sql);
StringBuffer sb = new StringBuffer();
int indx = 1; // Parameter begin with index 1
while (matcher.find()) {
matcher.appendReplacement(sb,String.valueOf(sqlArrya[indx]));
}
matcher.appendTail(sb);
System.err.println("Executing Query [" + sb.toString() + "] with Database[" + "] ...");
} catch (Exception ex) {
System.err.println("Executing Query [" + sql + "] with Database[" + "] ...");
}
}
Slightly different approach from all answers here,
If you are familiar with Debugging options in Eclipse. You may try the following:
Set a Breakpoint at stmt.executeQUery();
Right click your application, say Debug As select Java Application (or Whatever applicable in your case i.e. may be SpringBoot App etc.
Perform step that gets you to code mentioned in the Question.
If you check Variables tab in Debug Perspective of Eclipse, you will find variables like myQuery , stmt (according to your code)
Whatever you see as value of stmt would be the full SQL query you need.
Also, if you don't want to keep looking at this variable always you may try Java Logging and Print your Full SQL query in Logs.
I am working a Airsoft application.
I'm trying to add records to a MS Access Database via SQL in Java. I have established a link to the database, with the following:
try
{
//String Driver = "sun.java.odbc.JdbcOdbcDriver";
Class.forName("net.ucanaccess.jdbc.UcanaccessDriver");
Connection conn = DriverManager.getConnection("jdbc:ucanaccess://" + URL,"","");
Statement stmt = conn.createStatement();
System.out.println("Connection Established!");
ResultSet rs = stmt.executeQuery("SELECT * FROM AirsoftGunRentals");
tblRent.setModel(DbUtils.resultSetToTableModel(rs));
}
catch(Exception ex)
{
JOptionPane.showMessageDialog(null, "Error");
}
I am using Ucanaccess to access my MS database. It is reading the database and is displaying to a JTable. However, I need to create three JButtons to add, delete and update the table. I have tried to code the add button, and I have tried to add a record, but it crashes and gives me errors.
try
{
//String Driver = "sun.java.odbc.JdbcOdbcDriver";
Class.forName("net.ucanaccess.jdbc.UcanaccessDriver");
Connection conn = DriverManager.getConnection("jdbc:ucanaccess://" + URL,"","");
Statement stmt = conn.createStatement();
System.out.println("Connection Established!");
String Query= "INSERT INTO AirsoftGunRentals(NameOfGun, Brand, TypeOfGuns, NumberOfMagazines,Extras,NumberAvailable,UnitRent)"+
"VALUES('"+pName+"','"+pBrand+"','"+pTypeOfGun+"','"+pNumMags+"','"+pExtras+"','"+pNumberAvail+"','"+pRent+"');";
ResultSet rs = stmt.executeQuery(Query);
JOptionPane.showMessageDialog(null, "Success!");
}
catch(Exception ex)
{
JOptionPane.showMessageDialog(null, "Error");
}
I have attempted all three, hoping for a result. But am still getting big errors. The only difference between the buttons is that one adds, one deletes and one updates the table. Other then that, the code is the same, minus variables.
As Brahim mentionned it, you should use stmt.executeUpdate(Query) whenever you update / insert or delete data. Also with this particular query, given your String concatenation (see end of line), there is no space between the ")" and the "VALUES" which probably causes a malformed query.
However, I can see from your code that you are not very experienced with such use-cases, and I'd like to add some pointers before all hell breaks loose in your project :
Use PreparedStatement instead of Statement and replace variables by placeholders to prevent SQL Injection.
The code that you are using here is extremely prone to SQL injection - if any user has any control over any of the variables, this could lead to a full database dump (theft), destruction of data (vandalism), or even in machine takeover if other conditions are met.
A good advice is to never use the Statement class, better be safe than sorry :)
Respect Java Conventions (or be coherent).
In your example you define the String Query, while all the other variables start with lower-case (as in Java Conventions), instead of String query. Overtime, such little mistakes (that won't break a build) will lead to bugs due to mistaking variables with classnames etc :)
Good luck on your road to mastering this wonderful language ! :)
First add a space before the quotation marks like this :
String Query= "INSERT INTO AirsoftGunRentals(NameOfGun, Brand, TypeOfGuns, NumberOfMagazines,Extras,NumberAvailable,UnitRent) "+
" VALUES('"+pName+"','"+pBrand+"','"+pTypeOfGun+"','"+pNumMags+"','"+pExtras+"','"+pNumberAvail+"','"+pRent+"');";
And use stmt.executeUpdate(Query); instead of : stmt.executeQuery(Query);in your insert, update and delete queries. For select queries you can keep it.
I managed to find an answer on how to add, delete and update records to a MS Access DB. This is what I found, after I declared the connection, and the prepped statement. I will try to explain to the best I can. I had to add values individually using this:
(pstmt = Prepped Statement Variable)
pstmt.setWhatever(1,Variable);
And it works fine now. I use the same method to delete and update records.
This is the basic query format:
String SQLInsert = "INSERT INTO Tbl VALUES(NULL,?,?,?,?)";
The NULL in the statement is the autonumber in the table. and .setWhatever() clause replaces the question marks with the data types. Thus manipulating the database.
Thank you everyone for all your contributions. It helped a lot, and made this section a lot more understandable.