tags:

views:

544

answers:

7

I have what I'm sure is a fairly common issue, and I don't want to re-invent the wheel. I have a search form where users can specify search criteria and type of search (AND OR Ext..).

The form passes back id's that map to column names and values. Currently, I'm using server side Java to glue the strings together into a where clause. It works in some cases, but it's clunky, error prone and will not scale well.

Any suggestions?

Thanks,

David

A: 

You have to build the search string either on the client or on the server. Building it on the client is obviously not a good solution (security-wise), so the only option is to build it on the server. Personally, I would use or build a Searcher object, which handles the recurring task of building search strings effeciently and creates a Statement from there.

simon
+1  A: 

If you were using an ORM (I use Hibernate), you could use the Criteria API: it lets you agregate conditions (using a loop for example), and builds the resulting query.

In native SQL, I don't know a library that would do that. Maybe you could write your own, getting some inspiration from the documentation and code for Hibernate Criteria ?


OR:

If you do something sufficiently complex on the client (say you manage priorities between AND and OR, you can nest conditions using parenthesis ...), then you're probably already building a data structure that handles this on the client.

In that case, I suggest you send that data structure to the server, and use it via loops to build your query.

KLE
A: 

Hibernate has a Criteria API which allows to create dynamic queries using only method invocation, with no need for manual composition of the sql query.

But you should consider using a solution for full text search like Lucene or Hibernate Search, which greatly reduce the need for queries with complex condition. Full text search is also a much better solution for the user experience, as a full text search is simpler to perform and usually provides better results.

Massimiliano Fliri
+1  A: 

I'd use prepare and ? for parameters anyway, if only to avoid injection and other misconversion risks.

If your search criteria are limited in size, you can statically list all possible queries to prepare.

If not, you can maintain a pool of prepared queries dynamically. This is not as useful for a web app, where you probably won't get to reuse any of the queries you prepare.

reinierpost
A: 

Massimiliano Fliri's suggestion to look at the Criteria API got me headed in the right direction. I stopped thing about building "just a where clause" and started thinking about this as a need to build statements.

This lead me to a solution: Squiggle-sql: http://code.google.com/p/squiggle-sql/

From the docs:

Squiggle is a little Java library for dynamically generating SQL SELECT statements. It's sweet spot is for applications that need to build up complicated queries with criteria that changes at runtime. Ordinarily it can be quite painful to figure out how to build this string. Squiggle takes much of this pain away.

David Hamilton
FYI: Upon initial glance, that library does not appear to support prepared statements and parameters. For example, Strings appear to embedded directly in the SQL generated by the library. This MAY lead to SQL injection attack vulnerabilities. I could be wrong...
Adam Paynter
A: 

If you are using Hibernate as ORM then use the Criteria api to do this. It must easier to add/remove clauses based on some conditions.

If you are building a jdbc query keep the part that is constant first and append the varying part for e.g

select * from trans where userid = ?

and append based on conditions e.g
if amount != null then append ' and amount > ? '

As long as you can keep the constant part well segregated from the varying part you should not have much problem.

Rajat
A: 

The book "Expert SQL Server 2005 Development" by Adam Machanic has some excellent suggestions in chapter 7 concerning dynamic SQL. He dives into all kinds of issues including performance, maintainability, and security. I won't attempt to rewrite his chapter - suffice to say that he believes less is more when it comes to SQL.

It's specific to SQL Server but I believe his general approach (huge where clause vs. if/then SQL vs. dynamic) can be applied across the board.

EDIT: I think it's worthwhile to add... never trust input from the client, always parameterize your input before using it in SQL.

Mayo