data67 has asked for the wisdom of the Perl Monks concerning the following question:

Problem:
I have a web search form that searches a table with six available search fields. For example, consider we have an employee table with employee name, address and email fields.

I have to figure out a way to build an sql query with an "AND" clause that will construct the query dynamically based on which of the above fields had data in them?

There is probably an easy way to build the SQL dynamically but i am having trouble finding an easy way to do this.

I will really appreciate an example where you grab from "param("blah")" and build the sql on the fly.

Thank you for all your help.

  • Comment on Build SQL on the fly from WEB search form

Replies are listed 'Best First'.
Re: Build SQL on the fly from WEB search form
by jZed (Prior) on Sep 30, 2006 at 20:21 UTC
    Take a look at SQL::Abstract ... it provides easy ways to generate SQL from form or other data.
      This is a hosted server and SQL::Abstract module is not available. Is there another way?
Re: Build SQL on the fly from WEB search form
by artist (Parson) on Sep 30, 2006 at 22:41 UTC
Re: Build SQL on the fly from WEB search form
by stonecolddevin (Parson) on Oct 01, 2006 at 04:00 UTC

    1. Can we see some code?
    2. Have you tried asking your system administrator to install SQL::Abstract for you?

    meh.
Re: Build SQL on the fly from WEB search form
by graff (Chancellor) on Oct 01, 2006 at 14:28 UTC
    You say there are "six available search fields", so let's consider a realistic example -- a set of parameters like: firstname, lastname, street, city, state, zip, phone. In order to run a dynamic search on any combination of values in those parameters, you could do something like this:
    my @param_names = qw(firstname lastname street city state zip phone); # if column names in the table are different from param names in the f +orm, # you'll need a second array for the column names: my @table_names = qw(fname lname street city st zip phone); my @query_values; my @where_clauses; for my $i ( 0..$#param_names ) { $_ = param( $param_name[$i] ); s/^\s+//; # remove any leading and trailing whitespace s/\s+$//; if (length()) { # anything left? push @query_values, $_; # hold onto the value push @where_clauses, "$table_names[$i] = ?"; # use a placeholder in the sql statement } } if ( @where_clauses ) { my $sql = "select fname,lname,street,id,and_so_on from the_table w +here ". join( " and ", @where_clauses ); my $sth = $dbh->prepare( $sql ); $sth->execute( @query_values ); # do what you want with the query results (fetch_whatever) # ... } else { # no parameters were filled in, so what should you do? # - tell the client to try again, or # - query for and deliver the full table contents? }
    That will handle searches for exact matches to specific fields. If you want to support more flexible matches, you could provide a button for the client to pick "equals" vs. "like" for each parameter, and adjust the where_clause condition and query_value string accordingly (e.g., if the "like" button was chosen, use "like" instead of "=" in the where_clause string, and add "%" at the beginning and end of the query_value string).

    You might need to do other things with the param value strings before moving them into the query_value array (e.g. uri_unescape), in order for the query to work as intended.

Re: Build SQL on the fly from WEB search form
by Jenda (Abbot) on Oct 01, 2006 at 08:54 UTC

    Not sure what your database is as you did not tell us, but it it does allow stored procedures then the most efficient way is to create a stored procedure containing a structure of IFs and a separate SELECT for each combination. That way the server can prepare and store execution plans for each of the cases. You of course do not have to write all those selects by hand, you can generate them

    IF (@Name is NULL) IF (@Address is NULL) IF (@Email is NULL) SELECT ... FROM TheTable ELSE SELECT ... FROM TheTable WHERE Email like @Email + '%' ELSE ...
    If the SELECTs are more complex or involve complex views then you can save the database server a lot of work regenerating the execution plan.