Oracle SQL query without all parameters - java

Got this sql (selection between ranks):
//Variables come from outside or other classes etc...
"SELECT * from users where dept_name= ? AND birth_date >=? AND birth_date <=? AND money >=? AND money <=?;
//Long preparedStatement code...
Using the next code to pass dept_name to the sql:
System.out.println("Insert department name: ");
Scanner alpha = new Scanner(System.in);
String dept_name= alpha.nextLine();
What happens if I don't insert anything on the scanner and I simply press enter? Like if I want to skip the search by dept_name and I only want to search between birth_date and money ranks?
How can I handle:
pstmt.setString(1, users.getDeptname()); //prepared statement
If it previously received a "enter" as character on the dept_id ?
How can Oracle ignore dept_name =? if no valor is passed in the "?" with prepared statement and use the next fields in the SQL to continue the query?

You can modify the query to something like
SELECT * FROM users
WHERE (dept_name = ? OR ? IS NULL) AND .....
Then in the code you setting pstmt.setString(1, dept_name); pstmt.setString(2,dept_name);
However, I'd rather have multiple statements then one that fits all. The problem with any universal approach is performance. Optimizer will not be able to generate good execution plan . For instance, if username is set, range/unique scan of underlying index is definitely preferable over full table scan. Even though Oracle 11 and higher has nice features like bind awareness, I'm not 100% sure it will handle all the cases in optimal way.

Related

Java Prepared Statement with CONTAINS query

I have a search query which must search a column in a table using contains search. There is ctxsys.context type index on the column. While fetching data on the table using prepared statement, the search query is not able to process special characters like -,/,_ etc.
Here is my code -
String query = "select * from parties where contains (party_name ,'%' || ? || '%')>0";
PreparedStatement ps = con.prepareStatement(query);
ps.setString(1, searchName);
The code works fine for text which doesn't have special characters.
When I run the below query in sqlDeveloper it runs fine .
select * from parties where contains(party_name,'c/o')>0;
Please suggest what changes should I make in the prepared statement to make it work for special characters too.
Please refer to this question on how to use contains in prepared statement.
PreparedStatement with CONTAINS query
You have to use escape in your queries if the above didint work
like
SELECT * FROM BIRDS WHERE SPECIES='Williamson's Sapsucker
statement.executeQuery("SELECT * FROM BIRDS WHERE SPECIES='Williamson/'s Sapsucker' {escape '/'}");
reference from http://www.jguru.com/faq/view.jsp?EID=8881

Fetching records from MySQL using LIKE and %

I have table called mpi which contains 23 columns. I have introduced the search field with button for every column where user can enter the query to fetch the records using query
query="select * from mpi where Genus ='"+genus+"'
Now I want to fetch records by giving keywords using LIKE %% but it is not working and not giving any records but if type type the full name it is working perfectly. Here is the code
String uname=request.getParameter("uname");
String full="%"+uname+"%";
dbconn=new DatabaseConnection();
conn=dbconn.setConnection();
pstmt=conn.prepareStatement("select * from mpi where Genus LIKE ?");
pstmt.setString(1, full);
res=pstmt.executeQuery
Could any one tell me where is the mistake and why I am not getting the records when I use half keyword like %keyword%.
It works (apart from the missing parentheses) and the approach with a prepared statement is entirely correct.
However I have seen a couple of code pieces like that, and always the problem lay with variables mix-up or not closing, or simple oversight. Better declare as close as possible.
try (ResultSet res = pstmt.executeQuery()) {
while (res.next()) {
..
}
} // Automatically closes res.
Also handle the life-cycle of pstmt correctly, with closing.

java prepared statement

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

using java variable in sql statement

I'm trying to build a web page to better learn Java and SQL. My question is, is there a way in Java to make a generic SQL select statement? For example:
SELECT var1 FROM var2 WHERE var3=var4
or something of the sort.
My idea is to fill the vars with user selected items from the web page. I know this can be done in PHP using the Post method, but I'm not using PHP. Also, I've read about the Prepared Statement in Java, but seems only to work when the used after the comparison operator; ex:
SELECT * FROM table Where attr = ? &
Also, I do know i can do the hard coded version of "SELECT " + var1 + "FROM " + var2 + "WHERE attr = " + var3 + " " but that doesn't seem very generic and prone to a lot of errors.
Incase: I'm trying to build this test page using HTML & JSP.
What you are doing with the ? is parameterizing the query. The query can only be parameterized for values not names of tables or columns.
Every time you run a query. The database has to create a query plan. If you are running the same query again and again, you can reduce this overhead by creating a PreparedStatement.
The first execution of PreparedStatement will generate the query plan. The subsequent executions will reuse the same plan.
Same query here means, it is identical in all respects except values used in where clause, expressions etc.
If you change the Column or Table name or modify the structure of the query, then it is a different query and will require a different query plan. A PreparedStement is not useful in this case and you should stick to the hardcoded version you talked about. Because of this reason you will get an error if you try to parameterize Table or Column names in PreparedStement.
Having said that. It is not advisable to take such a generic approach for queries. If your queries are that simple, you can benefit from ORM tools. You would not have to maintain even a line of SQL. For complex queries you have an option of using ORM specific query language or JPQL or Native SQL. Look for JPA + Hibernate
Your specific usage is not permitted by JDBC. You need to hard code the table name when creating the prepared statement. If you really do want to do that I suggest you use String concatenation to create the SQL statements and then create a PreparedStatement with parameters to handle the where part. In case you are wondering why bother with PreparedStatements in the specific solution, it's to avoid SQL injection.
You can use PreparedStatement to achive your objective.
For example -
String query = "SELECT * FROM table Where attr = ?";
PreparedStatement pt = con.prepareStatement(query);
pt.setString(1, attribete);
pt.executeUpdate();
There is no such direct provision in any of SQL packaged classes or others to replace table, column names along with query parameter values, in a query string, using a single method.
You require to depend on both PreparedStatement and any of String methods replace(...) and replaceFirst(...) to achieve your requirement.
String sql = "Select $1, $2 from $3 where $4=? and $5=?";
sql = sql.replaceFirst( "$1", "col1_name" );
sql = sql.replaceFirst( "$2", "col2_name" );
sql = sql.replaceFirst( "$3", "table_name" );
sql = sql.replaceFirst( "$4", "col4_name" );
sql = sql.replaceFirst( "$5", "col5_name" );
// .. and so on
PreparedStatement pst = con.prepareStatement( sql );
// use relevant set methods to set the query parametrs.
pst.setXXX( 1, value_for_first_query_parameter ); // from a variable or literal
pst.setXXX( 2, value_for_second_query_parameter); // from a variable or literal
// ... and so on
If you are using JDBC, can try this
PreparedStatement statement = connection.prepareStatement("SELECT ? FROM ? WHERE ?=? ");
then
statement.setString(1, "column_name");
statement.setString(2, "table_name");
statement.setString(3, "column_name");
statement.setBigDecimal(4, 123);
If you are using other ORM like Hibernate or JPA, I believe there are also ways to do.

ORA-00933: SQL command not properly ended: java

I am taking domains from a text file and passing it to a query one by one.
for first time the query is executing fine .. but when it takes the second domain and passing it to query getting error "ORA-00933: SQL command not properly ended"
Below is the code
sql.append("select person_org_id,profile_type_id as NEXUS, profile_option_id,profile_option_value from TABLE1 ");
sql.append(" where profile_type_id=1 and person_org_id in (select person_org_id from TABLE2 where ");
sql.append(" account_id in (select account_id from TABLE3 where prod_id=10001 and prod_inst_name = ?)) ");
ps = con.prepareStatement(sql.toString());
System.out.println("----------checkpoint -----------");
ps.setString(1,domain_name);
System.out.println("----------checkpoint 4-----------");
rs= ps.executeQuery();
System.out.println("----------checkpoint 5-----------");
If you have this code in a loop, and you do not clear the StringBuilder or use a new one, then the second time around, you will have the SQL statement twice and that would explain the error.
Why use a StringBuilder at all if a simple String would do? There is no variation in the SQL statement at all. Of course, this may have been a simplified example.
Also, if you do this in a loop, and the SQL is indeed the exact same one every time, you could just prepare the statement once, and execute it repeatedly in the loop. That is kind of what prepared statements are for.

Categories

Resources