I want to capture the cost numbers from the query plan you get when you 'Explain' a query. Is there any way to get at this data inside of a Java ResultSet(or similar object)?
Sure, just run it as a regular statement:
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("explain analyze select * from foo");
while (rs.next())
{
System.out.println(rs.getString(1));
}
In addition to the answer supplied above, I would suggest that you make use of the ability to format EXPLAIN plans as XML in PostgreSQL 9.0 and later.
EXPLAIN ( analyze on, format xml ) SELECT ...
This will give you explain output you can more easily work with in Java by manipulating it as XML.
An other example with PreparedStatement, this time.
Like this:
PreparedStatement preparedStatement = connection.prepareStatement("EXPLAIN (ANALYZE true , VERBOSE true , BUFFERS true)" +
"SELECT * FROM Table");
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
System.out.println(resultSet.getString(1));
}
Or with a bind parameter:
PreparedStatement preparedStatement = connection.prepareStatement("EXPLAIN (ANALYZE true , VERBOSE true , BUFFERS true)" +
"SELECT * FROM Player WHERE id = ?");
preparedStatement.setLong(1, 1);
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
System.out.println(resultSet.getString(1));
}
Related
When I use the following code it runs perfectly.
PreparedStatement st = con.prepareStatement("select * from users where username=?");
st.setString(1, userId);
ResultSet rs = st.executeQuery();
But when I am using the following code, I get an error that userId (that I pass as parameter) is an invalid column name.
Statement st = con.createStatement();
ResultSet rs = st.executeQuery("select * from users where username="+userId);
Why statement method doesn't work and I have to use PreparedStatement?
User ID is a string (SQL calls this type CHAR or VARCHAR), it must be put in quotes if used in the SQL requests. Like this:
select * from users where username='12345'
PreparedStatement is much better solution because of the SQL injection. You CANNOT just write:
ResultSet rs = st.executeQuery("select * from users where username=\""+userId+"\"");
WRONG CODE - ^^^^^^^^^^^^^^^
because user ID can contains control characters like ['], ["] or [\]. It depends on the SQL server and sometimes are more sophisticated than it looks like. If using PreparedStatement, it is automatically managed by the JDBC driver.
First of all, is better to use the first one. But if you really want to use the second one, you need to put your value into quotes. Simple add the quotes to the value. But is good to create a function to it, if you are going to use it a loot. Like:
public String doubleQuoted(String value){
return "\"" + value + "\"";
}
or
public String singleQuoted(String value){
return "'" + value + "'";
}
and use
ResultSet rs = st.executeQuery("select * from users where username="+singleQuoted(userId));
You need to put strings into quotes:
Statement st = con.createStatement();
ResultSet rs = st.executeQuery("select * from users where username=\'"+userId+"\'");
\ is the escape character.
Note:
Your prepared statement is the preferred way of handling SQL queries. See #30thh answer as to why (SQL Injection attacks).
How do I set Dynamic query parameters in Apache drill. I tried and received error message saying: java.sql.SQLFeatureNotSupportedException:
Prepared-statement dynamic parameters are not supported.
Is it true that drill does not support such a feature, as in:
String sql = "select employee_id,first_name,last_name from dfs.'employee.json' where id = ?";
PreparedStatement preparedStatement = conn.prepareStatement(sql);
preparedStatement.setString(1, 23);
ResultSet rs = preparedStatement.executeQuery(sql);
Can any one please suggest a work around for this, if there's any
As of now, this support is not there. Drill does not support Prepared-statement dynamic parameters.If still some one wants to go ahead with such dynamic parametres for their queries, they would have to set using statements this way:
Statement statement = connection.createStatement();
String queryParam = "Computers"
String sqlQuery = "select employee_id,first_name,last_name from dfs.'employee.json' where department LIKE'" +queryParam +"'"+"and conditions<...> ";
ResultSet rs = statement.executeQuery(sqlQuery);
while(rs.next)
{
do as you need
}
I'm searching on the web for several times but did not found anything which could help me (in java).
In fact I need to search in a sql table some rows from some reference which contains an hyphen. The issue made is that the sql replace my reference by the result of a substraction. The type of the columns are string.
Statement stmt = con.createStatement();
String query = "SELECT * FROM WAREHOUSE WHERE REF LIKE('96-18')" ;
Statement statement = con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
ResultSet rs = statement.executeQuery(query);
while (rs.next()) {
System.out.println(rs.getString("S_FAMILY"));
}
In this code, it replaces my reference by 78 and does not naturaly return the good result.
I've searched for an escape char but did not found.
Try sending the String as parameter on the query. Doing this requires to change the Statement into PreparedStatement:
String query = "SELECT * FROM WAREHOUSE WHERE REF LIKE(?)" ;
PreparedStatement pstatement = con.prepareStatement(query,
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
pstatement.setString(1, "96-18");
ResultSet rs = pstatement.executeQuery();
Note: you should send "96-18" as value of a String variable, do not hard code it.
You can try
SELECT * FROM WAREHOUSE WHERE REF LIKE('96\-18') ESCAPE '\'
Hope it helps
String poster = "user";
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM `prices` WHERE `poster`="+poster);
This does not work.Any tips or tricks would be appreciated.
Try surrounding the poster variable with single quotes, like this:
ResultSet rs = stmt.executeQuery("SELECT * FROM `prices` WHERE `poster`='"+poster+"'");
That's because SQL expects strings to be surrounded by single quotes. An even better alternative would be to use prepared statements:
PreparedStatement stmt = con.prepareStatement("SELECT * FROM `prices` WHERE `poster` = ?");
stmt.setString(1, poster);
ResultSet rs = stmt.executeQuery();
It's recommended using PreparedStatement since the way you are currently building the query (by concatenating strings) makes it easy for an attacker to inject arbitrary SQL code in a query, a security threat known as a SQL injection.
1) In general, to "parameterize" your query (or update), you'd use JDBC "prepared statements":
http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html
2) In your case, however, I think all you need to do is add quotes (and lose the back-quotes):
// This is fine: no back-quotes needed
ResultSet rs = stmt.executeQuery("SELECT * FROM prices");
// Since the value for "poster" is a string, you need to quote it:
String poster = "user";
Statement stmt = con.createStatement();
ResultSet rs =
stmt.executeQuery("SELECT * FROM prices WHERE poster='" + poster + "'");
The Statement interface only lets you execute a simple SQL statement with no parameters. You need to use a PreparedStatement instead.
PreparedStatement pstmt = con.prepareStatement("
select * from
prices where
poster = ?");
pstmt.setString(1, poster);
ResultSet results = ps.executeQuery();
Is there a way to retrieve the auto generated key from a DB query when using a java query with prepared statements.
For example, I know AutoGeneratedKeys can work as follows.
stmt = conn.createStatement();
stmt.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS);
if(returnLastInsertId) {
ResultSet rs = stmt.getGeneratedKeys();
rs.next();
auto_id = rs.getInt(1);
}
However. What if I want to do an insert with a prepared Statement.
String sql = "INSERT INTO table (column1, column2) values(?, ?)";
stmt = conn.prepareStatement(sql);
//this is an error
stmt.executeUpdate(Statement.RETURN_GENERATED_KEYS);
if(returnLastInsertId) {
//this is an error since the above is an error
ResultSet rs = stmt.getGeneratedKeys();
rs.next();
auto_id = rs.getInt(1);
}
Is there a way to do this that I don't know about. It seems from the javadoc that PreparedStatements can't return the Auto Generated ID.
Yes. See here. Section 7.1.9. Change your code to:
String sql = "INSERT INTO table (column1, column2) values(?, ?)";
stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
stmt.executeUpdate();
if(returnLastInsertId) {
ResultSet rs = stmt.getGeneratedKeys();
rs.next();
auto_id = rs.getInt(1);
}
There's a couple of ways, and it seems different jdbc drivers handles things a bit different, or not at all in some cases(some will only give you autogenerated primary keys, not other columns) but the basic forms are
stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
Or use this form:
String autogenColumns[] = {"column1","column2"};
stmt = conn.prepareStatement(sql, autogenColumns)
Yes, There is a way. I just found this hiding in the java doc.
They way is to pass the AutoGeneratedKeys id as follows
String sql = "INSERT INTO table (column1, column2) values(?, ?)";
stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
I'm one of those that surfed through a few threads looking for solution of this issue ... and finally get it to work. FOR THOSE USING jdbc:oracle:thin: with ojdbc6.jar PLEASE TAKE NOTE:
You can use either methods:
(Method 1)
Try{
String yourSQL="insert into Table1(Id,Col2,Col3) values(SEQ.nextval,?,?)";
myPrepStatement = <Connection>.prepareStatement(yourSQL, Statement.RETURN_GENERATED_KEYS);
myPrepStatement.setInt(1, 123);
myPrepStatement.setInt(2, 123);
myPrepStatement.executeUpdate();
ResultSet rs = getGeneratedKeys;
if(rs.next()) {
java.sql.RowId rid=rs.getRowId(1);
//what you get is only a RowId ref, try make use of it anyway U could think of
System.out.println(rid);
}
} catch (SQLException e) {
//
}
(Method 2)
Try{
String yourSQL="insert into Table1(Id,Col2,Col3) values(SEQ.nextval,?,?)";
//IMPORTANT: here's where other threads don tell U, you need to list ALL cols
//mentioned in your query in the array
myPrepStatement = <Connection>.prepareStatement(yourSQL, new String[]{"Id","Col2","Col3"});
myPrepStatement.setInt(1, 123);
myPrepStatement.setInt(2, 123);
myPrepStatement.executeUpdate();
ResultSet rs = getGeneratedKeys;
if(rs.next()) {
//In this exp, the autoKey val is in 1st col
int id=rs.getLong(1);
//now this's a real value of col Id
System.out.println(id);
}
} catch (SQLException e) {
//
}
Basically, try not used Method1 if you just want the value of SEQ.Nextval, b'cse it just return the RowID ref that you may cracked your head finding way to make use of it, which also don fit all data type you tried casting it to! This may works fine (return actual val) in MySQL, DB2 but not in Oracle.
AND, turn off your SQL Developer, Toad or any client which use the same login session to do INSERT when you're debugging. It MAY not affect you every time (debugging call) ... until you find your apps freeze without exception for some time. Yes ... halt without exception!
Connection connection=null;
int generatedkey=0;
PreparedStatement pstmt=connection.prepareStatement("Your insert query");
ResultSet rs=pstmt.getGeneratedKeys();
if (rs.next()) {
generatedkey=rs.getInt(1);
System.out.println("Auto Generated Primary Key " + generatedkey);
}