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

Hi All

I am trying to build a where clause to use in a DBIx::Class query.

Scenario:
A user can search for a name by typing in one or more words in a search field. Multiple words will be separated by a blank space.
If the search field contains multiples words the application will split the search term into an array, then use the array to build the where
clause. Note: A name can be made up of many words (ie: Orlando Miguel Jose Fernando). So, I want to be able to use the each
of the search term words to build the where clause.

The SQL query would look like so:
SELECT *
FROM People
WHERE Name like "%Orlando%' AND
Name like '%Miguel%' AND
Name like '%Jose%' AND
Name like '%Fernando%

The order of the words in the where clause is irrelevant, since it
will still return a result set that matches that condition, if the record(s) exist.

If I manually write out the DBIx::Class code, it would appear as follows:

my @results = $schema->( 'People' )->search({ Name => [ -and => { like => '%Orlando%' }, { like => '%Miguel%' }, { like => '%Jose%' }, { like => '%Fernando%' } ] } );

After I split the search term into an array, how can I build the where clause with each item,
to represent the where clause in the DBIx::Class query, above? I attempted many ways with no
success. The code would look something like this:

if($search_term =~ /\s+/) { my @search_term_array = split /\s+/, $search_term; my $whrcls: foreach my $searchitem (@search_term_array) { $whrcls = ...... ..... ..... } } my @results = $schema->( 'People' )->search({ Name => [ -and => $whrcls ] } );

I know I am missing something, after searching via Google, I am at a dead end.
Any ideas or a document you can direct me to?

Thanks

-Phil-

Replies are listed 'Best First'.
Re: Trying to build a where clause to insert into a DBIx::Class Query
by 1nickt (Canon) on Jan 29, 2018 at 03:40 UTC

    Hi, try this:

    use strict; use warnings; use feature 'say'; use SQL::Abstract; my $input = 'Orlando Miguel Jose Fernando'; my @match = map { +{ 'like' => qq{'%$_%'} } } split ' ', $input; my %where = ( Name => [ -and => @match ] ); my $sqla = SQL::Abstract->new; my ($sql, @bind) = $sqla->select('People', undef, \%where); say $sql; say for @bind; __END__
    Output:
    $ perl 1208017.pl SELECT * FROM People WHERE ( ( Name LIKE ? AND Name LIKE ? AND Name LI +KE ? AND Name LIKE ? ) ) '%Orlando%' '%Miguel%' '%Jose%' '%Fernando%'

    Hope this helps!


    The way forward always starts with a minimal test.

      Thanks 1nickt,

      That work. The only thing I had to do was to modify the mapping. You had qq{'%$_&'}.
      For whatever reason, DBIx::Class produced ''%Orlando%'', ''%Miguel%'', ''%Jose%'', ''%Fernandez%''.
      So, I removed the single quote from the mapping, qq{%$_%}, then it work perfectly.

      Thanks again for your help.

      -Phil-