I have 9 fields to my user interface , each one is representing a column in my database table.
So the problem is that i need to cover all the possible combinations of the 9 fields and send specific queries to the database.
Example :
If the user puts 2 fields , i return all the items from the DB that matches to the combination of these 2 items.
If the user puts 3 fields , i return all the items from the DB that matches to the combination of these 3 items.
Its obvious that the combinations are 100+ if you calculate them.
Using JAVA and MySQL with JDBC driver, the Prepared Statement is provided which secures SQL Injection.
But this way , i should make 100+ functions just to cover all the combinations and the code will be repititive .
HOW I SOLVE IT :
I created a Query Generator which takes the input the user entered and creates an SQL QUERY as a String.
Then i pass it to the DB using the Statement Class . This way i cover all the possible combinations but i have to craft SQL Injection protection from zero by my own and generally it is a custom solution to a problem that i m sure its already solved.
If there is an official way to do this please let me know!
2
Answers
If the user have entered the value for some column then you provide entered criteria into the query else you provide NULL (
command.Parameters.AddWithValue("@columnX", (object)value ?? DBNull.Value)
).You have basically two possibilities to approach this problem.
The first one uses one statement with the OR conditions handling the missing criteria.
The second approach uses dynamically generated statement containing only the predicates with given values.
The drawback of the first solution is that you get one statement, i.e. one execution plan that handles all inputs.
The second solution allow to select the proper execution plan based on the input. The drawback is that you land with a different number of bind variables, which makes it technically difficult to handle.
Here comes in the idea popularized for years by Tom Kyte
You generate the predicate for each selection, but dependent on if the value is given or not:
The shortcut logic eliminates the predicates with no values but you get the complete number of bind variables in the prepared statement.
Example with three column all passed
Example with one input
Example with no input
Here the Oracle execution plan for the second example showing that only the
col1
predicate is evaluated, all other are discarded. Similar is valid for PostgreSQL, I did not test MySQL.For the third query (no criteria) you end with a
full table scan
So if the cardinality of the result is highly dependent on the selection this approach is more suitable that the one size fits all
OR
predicate solution.