I'm using a PreparedStatement in my code to make queries. For example:
PreparedStatement stmt = db.con.prepareStatement("select id from nodes where x>? and x<? and y>? and y<?");
stmt.setDouble(1, x1);
... //set a value for each param 1 thru 4
And now I have another query that wants to use the exact same query above as a subquery. So I could do:
PreparedStatement stmt2 = db.con.prepareStatement("select id from edges where startNodeId in
(select id from nodes where x>? and x<? and y>? and y<?)");
But that's repetitive and I'm likely to modify the first PreparedStatement and want those changes to propagate to the second one. Is there a way to set a prepared statement to be a subquery in another statement?
Perhaps something akin to stmt2.setPreparedStatement(2, stmt)?
Simply combine both the queries into one single SELECT statement.
SELECT x,y,z FROM tablez WHERE id IN (SELECT id FROM "your first query")
Related
I'm trying to execute following SQL query where it tries to find results that matches the column2 values ending with abc
PreparedStatement stmt = conn.prepareStatement("SELECT column1 FROM dbo.table1 WHERE column2 LIKE ?");
stmt.setString(1, "%" +"abc");
But it returns nothing even though there is a matching value. This only happens with SQL Server. Same query with informix database returns correct results. Anyone has an idea about what causing this to behave differently?
Is this due to an issue in how PreparedStatement creates the SQL query for SQL Server?
Edit
I found out this happens when the data in the column which i perform the like contain space. eg: when the column contains "some word" and if i perform the search by stmt.setString(1, "%" + "word"); it won't return a matching result but if i perform the same on for "someword" it would return the matching result
SQL Server accepts wild characters in the LIKE clause within the single quotation marks, like this ''.
A sample SQL query:
SELECT NAME FROM VERSIONS WHERE NAME LIKE 'Upd%'
The query above will yield you results on SQL Server. Applying the same logic to your Java code will retrieve results from your PreparedStatement as well.
PreparedStatement stmt = conn.prepareStatement("SELECT NAME FROM VERSIONS WHERE NAME LIKE ?");
stmt.setString(1, "Upd%");
I've tested this code on SQL Server 2012 and it works for me. You need to ensure that there are no trailing spaces in the search literal that you pass on to your JDBC code.
Though as a side note, you need to understand that a wildcard % used in the beginning, enforces a full table scan on the table which can deteriorate your query performance. A good article for your future reference.
Hope this helps!
i have same problem,i have done with the CONCATE function for this.
PreparedStatement ps = con.prepareStatement(
"SELECT * FROM analysis WHERE notes like CONCAT( '%',?,'%')";
ps.setString(1, notes);
ResultSet rs = ps.executeQuery();
I have a requirement like this...
Need to execute a java prepared statement example:
String sql = "select first_name from student where roll_no :=1";
connection.prepareStatement(sql);
But the problem is, sometimes there can be NO rows in the table for the above query.
In that case, I want to query the 2nd table say student2. Hence the sql query will be now:
String sql2 = "select first_name from student2 where roll_no :=1";
Is there a way to achieve this condition of selecting from another table(student2) in a single sql query.
I want something like this pseudo code:
String sql = "if student1 table doesn't have a roll_num, then query student2 table";
Create a database procedure which you call with the prepared statement
MySql,
Oracle.
Hope this helps
Though your design is not good, I am giving hint to achieve what you are asking. When you execute first query, just check are there any result sets available, if not then execute second query.
ResultSet rs = statement.execute();
if (!rs.next()){
//ResultSet is empty
}
In If block you need to execute second query.
Note: First rethink your design, if not possible. This solution works, a lame solution for lame problem :)
I think you could use e.g. UNION as:
select val from (select 'A' as val from DUAL
union
select 'B' as VAL from DUAL)
where rownum = 1;
but #tbraun89 is right think on your DB structure first
I have a prepared statement like this
stmt = select * from table_name where id IN (?);
Once I pass the parameters the stmt looks like way
stmt = select * from table_name where id IN ('1,2,3');
There is no error while executing the query. However the resultset is returned only for the id=1. Is there some way I can eliminate the quotes / get the resultset for all these id's.
stmt = select * from table_name where id IN (?);
select GROUP_CONCAT(id) id from table ;
if(rs.next()){
stmt.setString(1,rs.getString("id"));
stmt.executeQuery();
}
Thanks in advance.
It's not clear what the ID type is, but I believe you should actually be preparing a statement with each possible value as a separate parameter:
select * from table_name where id IN (?, ?, ?)
Then add the three values for the three parameters. It's a common problem with parameterized SQL - when you want to be able to specify a variable number of values, you need to vary the SQL. There may be a MySQL-specific way of coping with this (like table-valued parameters in SQL Server 2008) but I don't believe there's a generic JDBC way of doing this.
I am trying to execute 2 sql statements in a batch. the first statement is an insert that uses a auto generated value for its ID. the second statement is an insert to another table but it needs to use the auto generated value from above as part of the insert value
something like (where id is just to show the auto generated field its not defined in sql
stmt.addbatch(insert into table1("id_auto_generated", "foo"));
stmt.addbatch(insert into table2("table1_id", "boo"));
the way I do it now is by using this in my second sql
insert into table2(LAST_INSERT_ID(), "boo");
Problem is its slow even in batch statements its very slow as my batch can be 50,000 inserts.
I wanted to switch to prepared statements but do not know how to use Statement.RETURN_GENERATED_KEYS or LAST_INSERT_ID() with prepared statements.
I'm not sure this is a way you can do this with addBatch except in the manner that you are using. Another thing to try is to abandon the addBatch() method and try turning off auto-commit instead. Then you can use the stmt.getGeneratedKeys();. Something like:
connection.setAutoCommit(false);
stmt.executeUpdate("insert into table1(\"id_auto_generated\", \"foo\") ...");
DatabaseResults results = stmt.getGeneratedKeys();
// extract the id from the results
stmt.executeUpdate("insert into table2(\"table1_id\", \"boo\") ...");
... many more stmts here
connection.commit();
connection.setAutoCommit(true);
Hope this helps.
Following on from one of my previous questions to do with method design I was advised to implemented my SQL queries as a parameterized query as opposed to a simple string.
I've never used parameterized queries before so I decided to start with something simple, take the following Select statement:
String select = "SELECT * FROM ? ";
PreparedStatement ps = connection.prepareStatement(select);
ps.setString(1, "person");
This gives me the following error: "[SQLITE_ERROR] SQL error or missing database (near "?": syntax error)"
I then tried a modified version which has additional criteria;
String select = "SELECT id FROM person WHERE name = ? ";
PreparedStatement ps = connection.prepareStatement(select);
ps.setString(1, "Yui");
This version works fine, in the my first example am I missing the point of parameterized queries or am I constructing them incorrectly?
Thanks!
Simply put, SQL binds can't bind tables, only where clause values. There are some under-the-hood technical reasons for this related to "compiling" prepared SQL statements. In general, parameterized queries was designed to make SQL more secure by preventing SQL injection and it had a side benefit of making queries more "modular" as well but not to the extent of being able to dynamically set a table name (since it's assumed you already know what the table is going to be).
If you want all rows from PERSON table, here is what you should do:
String select = "SELECT * FROM person";
PreparedStatement ps = connection.prepareStatement(select);
Variable binding does not dynamically bind table names as others mentioned above.
If you have the table name coming in to your method as a variable, you may construct the whole query as below:
String select = "SELECT * FROM " + varTableName;
PreparedStatement ps = connection.prepareStatement(select);
Parameterized queries are for querying field names - not the table name!
Prepared statements are still SQL and need to be constructed with the appropriate where clause; i.e. where x = y. One of their advantages is they are parsed by the RDMS when first seen, rather than every time they are sent, which speeds up subsequent executions of the same query with different bind values.