Обсуждение: Incorrect Query

Поиск
Список
Период
Сортировка

Incorrect Query

От
Sharon Cowling
Дата:
Hi,

I'm working on an application, the user enters the customers id or their firstname or their lastname or their firstname
andlastname.  The problem is when they enter their firstname AND their lastname it returns as if you had entered either
theirfirstname OR their lastname.  I must be missing brackets somewhere, but I can't figure it out, I've tried
everythingI could think of, does anyone have any ideas?  

Query:
select person_id, initcap(firstname), initcap(lastname), dob, street, city
from person5
where person_id = ''
or ( ( firstname = initcap('sharon') )
or ( lastname = initcap('cowling') ) )
or ( ( firstname = initcap('sharon')
and lastname = initcap('cowling')  ) )
order by lastname;

Results:
 person_id | initcap | initcap  |    dob     | street  |    city
-----------+---------+----------+------------+---------+------------
      1018 | Katrina | Cowling  | 07/07/1976 | Long St | Wellington
       858 | Sharon  | Cowling  | 16/10/1979 | A Grove | Wellington
      1060 | Sharon  | O'neill  | 11/11/1977 | Fsddf   | Fdsfds
      1062 | Sharon  | O'ray    | 11/11/1977 | Dfs     | Sfsf
      1061 | Sharon  | O'reilly | 11/11/1977 | Sfds    | Sfdsfs
       880 | Sharon  | Smiley   | 16/11/1979 | The St  | The City
(6 rows)



sharon=> \d person5
                   Table "person5"
    Attribute     |         Type          | Modifier
------------------+-----------------------+----------
 person_id        | integer               | not null
 firstname        | character varying(25) | not null
 lastname         | character varying(25) | not null
 dob              | date                  | not null
 street           | character varying(50) | not null
 suburb           | character varying(50) |
 city             | character varying(50) | not null
 homephone        | character varying(15) |
 workphone        | character varying(15) |
 mobile           | character varying(15) |
 type             | character varying(30) | not null
 date_approved    | date                  | not null
 approved_by      | character varying(50) | not null
 vehicle_type     | character varying(50) |
 vehicle_rego     | character varying(6)  |
 drivers_licence  | character varying(10) |
 firearms_licence | character varying(20) |
 notes            | character varying(80) |
 status           | character varying(10) |
Indices: firstname_idx,
         fullname_idx,
         lastname_idx,
         person5_drivers_licence_key,
         person5_firearms_licence_key,
         person5_pkey


Regards,

Sharon Cowling



Re: Incorrect Query

От
Andrew McMillan
Дата:
On Wed, 2002-05-08 at 17:06, Sharon Cowling wrote:
> Hi,
>
> I'm working on an application, the user enters the customers id or
> their firstname or their lastname or their firstname and lastname.
>  The problem is when they enter their firstname AND their lastname
> it returns as if you had entered either their firstname OR their
> lastname.  I must be missing brackets somewhere, but I can't figure
> it out, I've tried everything I could think of, does anyone have
> any ideas?
>
> Query:
> select person_id, initcap(firstname), initcap(lastname), dob, street, city
> from person5
> where person_id = ''
> or ( ( firstname = initcap('sharon') )
> or ( lastname = initcap('cowling') ) )
> or ( ( firstname = initcap('sharon')
> and lastname = initcap('cowling')  ) )
> order by lastname;

Hi Sharon,

Several points here:

Firstly, you are presumably building this SQL in a program.  You should
probably look at the values for firstname and lastname in your program,
and construct your SQL differently, as appropriate.

If that's not possible, and you have to have a static SQL string that
you replace values into, then you will want to do something like this:

SELECT ...
  WHERE (firstname = '$fname' AND '' = '$lname' )
     OR (lastname = '$lname' AND '' = '$fname' )
     OR (firstname = '$fname' AND lastname = '$lname' )

This means that you compare firstname with $fname _only_ if $lname is
empty, and vice versa.  I'll leave it to you to decide if the person_id
= '' was doing the correct thing...

Thirdly, if you don't trust your database to contain 'initcap()' values
(looking at your output specifiers), how can you compare against
initcap() values in the where clause!  In the where clause you should
really be something like:
  WHERE lower(firstname) = lower('$fname') ...

Cheers,
                        Andrew.

PS. Say "Hi" to Andrew McClure from me :-)
--
--------------------------------------------------------------------
Andrew @ Catalyst .Net.NZ Ltd, PO Box 11-053, Manners St, Wellington
WEB: http://catalyst.net.nz/        PHYS: Level 2, 150-154 Willis St
DDI: +64(4)916-7201    MOB: +64(21)635-694    OFFICE: +64(4)499-2267
       Are you enrolled at http://schoolreunions.co.nz/ yet?


Re: Incorrect Query

От
Sharon Cowling
Дата:
Hi Andrew,

Sorry I should have said the values were just examples, its a java program so
the id, firstname, and lastname are variables taken from the user entry, I left
the id blank in the example as more often than not the user will only be
entering the persons name.

The names are stored with initcap() values in the database, but when the person
is doing a search to retrieve this data they may enter the name all in lower
case, so I probably don't need initcap() in the select clause, thanks for your
advice I will look at a different way of comparing the values in my java code.

I'll say hi to Andrew for you.

Regards,

Sharon Cowling



Quoting Andrew McMillan <andrew@catalyst.net.nz>:

> On Wed, 2002-05-08 at 17:06, Sharon Cowling wrote:
> > Hi,
> >
> > I'm working on an application, the user enters the customers id or
> > their firstname or their lastname or their firstname and lastname.
> >  The problem is when they enter their firstname AND their lastname
> > it returns as if you had entered either their firstname OR their
> > lastname.  I must be missing brackets somewhere, but I can't figure
> > it out, I've tried everything I could think of, does anyone have
> > any ideas?
> >
> > Query:
> > select person_id, initcap(firstname), initcap(lastname), dob, street, city
>
> > from person5
> > where person_id = ''
> > or ( ( firstname = initcap('sharon') )
> > or ( lastname = initcap('cowling') ) )
> > or ( ( firstname = initcap('sharon')
> > and lastname = initcap('cowling')  ) )
> > order by lastname;
>
> Hi Sharon,
>
> Several points here:
>
> Firstly, you are presumably building this SQL in a program.  You should
> probably look at the values for firstname and lastname in your program,
> and construct your SQL differently, as appropriate.
>
> If that's not possible, and you have to have a static SQL string that
> you replace values into, then you will want to do something like this:
>
> SELECT ...
>   WHERE (firstname = '$fname' AND '' = '$lname' )
>      OR (lastname = '$lname' AND '' = '$fname' )
>      OR (firstname = '$fname' AND lastname = '$lname' )
>
> This means that you compare firstname with $fname _only_ if $lname is
> empty, and vice versa.  I'll leave it to you to decide if the person_id
> = '' was doing the correct thing...
>
> Thirdly, if you don't trust your database to contain 'initcap()' values
> (looking at your output specifiers), how can you compare against
> initcap() values in the where clause!  In the where clause you should
> really be something like:
>   WHERE lower(firstname) = lower('$fname') ...
>
> Cheers,
>                         Andrew.
>
> PS. Say "Hi" to Andrew McClure from me :-)
> --
> --------------------------------------------------------------------
> Andrew @ Catalyst .Net.NZ Ltd, PO Box 11-053, Manners St, Wellington
> WEB: http://catalyst.net.nz/        PHYS: Level 2, 150-154 Willis St
> DDI: +64(4)916-7201    MOB: +64(21)635-694    OFFICE: +64(4)499-2267
>        Are you enrolled at http://schoolreunions.co.nz/ yet?
>


-------------------------------------------------
This mail sent through IMP: http://horde.org/imp/

Re: Incorrect Query

От
"Joshua b. Jore"
Дата:
Sharon,
You were abusing parentheses and confusing the issue. Don't do that, it
just makes the query less readable.

Here is what you actually wrote:

where
person_id = ''
or
(
   (
       firstname = initcap('sharon')
   )
   or
   (
       lastname = initcap('cowling')
   )
)
or
(
   (
       firstname = initcap('sharon')
       and
       lastname = initcap('cowling')
   )
)

Which is simplified to (removing parentheses where redundant but
retaining all the logic). Check out that first bit where you match on
fname or lname. That last bit doesn't even do anything since the other
name expressions covered it already.

where
person_id = ''
or
firstname = initcap('sharon')
or
lastname = initcap('cowling')
or
(
   firstname = initcap('sharon')
   and
   lastname = initcap('cowling')
)

Why not just use?

WHERE person_id = ''
OR (firstname = initcap('sharon')
    AND
    lastname = initcap('cowling')
   )


Re: Incorrect Query

От
Sharon Cowling
Дата:
Hi,

> Why not just use?
>
> WHERE person_id = ''
> OR (firstname = initcap('sharon')
>     AND
>     lastname = initcap('cowling')
>    )
>

Because the user may enter either just the firstname or just the lastname, so the above won't work if I just enter
'cowling'and there are multiple entries of 'cowling' in the database, it returns 0 rows. 


select person_id, initcap(firstname), initcap(lastname), dob, street, city
from person5
where person_id = ''
OR (firstname = initcap('')
AND
lastname = initcap('cowling')
);

 person_id | initcap | initcap | dob | street | city
-----------+---------+---------+-----+--------+------
(0 rows)

select person_id, initcap(firstname), initcap(lastname), dob, street, city
from person5
where
person_id = ''
or
firstname = initcap('')
or
lastname = initcap('cowling')
or
(
   firstname = initcap('sharon')
   and
   lastname = initcap('')
)

 person_id | initcap | initcap |    dob     | street  |    city
-----------+---------+---------+------------+---------+------------
      1018 | Katrina | Cowling | 07/07/1976 | Long St | Wellington
       858 | Sharon  | Cowling | 16/10/1979 | A Grove | Wellington

Regards,

Sharon Cowling


> -----Original Message-----
> From: Joshua b. Jore [mailto:josh@greentechnologist.org]
> Sent: Thursday, 9 May 2002 01:39
> To: Sharon Cowling
> Cc: Pgsql-Novice (E-mail)
> Subject: Re: [NOVICE] Incorrect Query
>
>
> Sharon,
> You were abusing parentheses and confusing the issue. Don't
> do that, it
> just makes the query less readable.
>
> Here is what you actually wrote:
>
> where
> person_id = ''
> or
> (
>    (
>        firstname = initcap('sharon')
>    )
>    or
>    (
>        lastname = initcap('cowling')
>    )
> )
> or
> (
>    (
>        firstname = initcap('sharon')
>        and
>        lastname = initcap('cowling')
>    )
> )
>
> Which is simplified to (removing parentheses where redundant but
> retaining all the logic). Check out that first bit where you match on
> fname or lname. That last bit doesn't even do anything since the other
> name expressions covered it already.
>
> where
> person_id = ''
> or
> firstname = initcap('sharon')
> or
> lastname = initcap('cowling')
> or
> (
>    firstname = initcap('sharon')
>    and
>    lastname = initcap('cowling')
> )
>
> Why not just use?
>
> WHERE person_id = ''
> OR (firstname = initcap('sharon')
>     AND
>     lastname = initcap('cowling')
>    )
>


Re: Incorrect Query

От
Sharon Cowling
Дата:
Hi,

Sorry for bothering the list, had a bad day yesterday, acheived the desired effect in Java code.

Regards,

Sharon Cowling



> -----Original Message-----
> From: pgsql-novice-owner@postgresql.org
> [mailto:pgsql-novice-owner@postgresql.org]On Behalf Of Sharon Cowling
> Sent: Thursday, 9 May 2002 08:01
> To: Joshua b. Jore
> Cc: Pgsql-Novice (E-mail)
> Subject: Re: [NOVICE] Incorrect Query
>
>
> Hi,
>
> > Why not just use?
> >
> > WHERE person_id = ''
> > OR (firstname = initcap('sharon')
> >     AND
> >     lastname = initcap('cowling')
> >    )
> >
>
> Because the user may enter either just the firstname or just
> the lastname, so the above won't work if I just enter
> 'cowling' and there are multiple entries of 'cowling' in the
> database, it returns 0 rows.
>
>
> select person_id, initcap(firstname), initcap(lastname), dob,
> street, city
> from person5
> where person_id = ''
> OR (firstname = initcap('')
> AND
> lastname = initcap('cowling')
> );
>
>  person_id | initcap | initcap | dob | street | city
> -----------+---------+---------+-----+--------+------
> (0 rows)
>
> select person_id, initcap(firstname), initcap(lastname), dob,
> street, city
> from person5
> where
> person_id = ''
> or
> firstname = initcap('')
> or
> lastname = initcap('cowling')
> or
> (
>    firstname = initcap('sharon')
>    and
>    lastname = initcap('')
> )
>
>  person_id | initcap | initcap |    dob     | street  |    city
> -----------+---------+---------+------------+---------+------------
>       1018 | Katrina | Cowling | 07/07/1976 | Long St | Wellington
>        858 | Sharon  | Cowling | 16/10/1979 | A Grove | Wellington
>
> Regards,
>
> Sharon Cowling
>
>
> > -----Original Message-----
> > From: Joshua b. Jore [mailto:josh@greentechnologist.org]
> > Sent: Thursday, 9 May 2002 01:39
> > To: Sharon Cowling
> > Cc: Pgsql-Novice (E-mail)
> > Subject: Re: [NOVICE] Incorrect Query
> >
> >
> > Sharon,
> > You were abusing parentheses and confusing the issue. Don't
> > do that, it
> > just makes the query less readable.
> >
> > Here is what you actually wrote:
> >
> > where
> > person_id = ''
> > or
> > (
> >    (
> >        firstname = initcap('sharon')
> >    )
> >    or
> >    (
> >        lastname = initcap('cowling')
> >    )
> > )
> > or
> > (
> >    (
> >        firstname = initcap('sharon')
> >        and
> >        lastname = initcap('cowling')
> >    )
> > )
> >
> > Which is simplified to (removing parentheses where redundant but
> > retaining all the logic). Check out that first bit where
> you match on
> > fname or lname. That last bit doesn't even do anything
> since the other
> > name expressions covered it already.
> >
> > where
> > person_id = ''
> > or
> > firstname = initcap('sharon')
> > or
> > lastname = initcap('cowling')
> > or
> > (
> >    firstname = initcap('sharon')
> >    and
> >    lastname = initcap('cowling')
> > )
> >
> > Why not just use?
> >
> > WHERE person_id = ''
> > OR (firstname = initcap('sharon')
> >     AND
> >     lastname = initcap('cowling')
> >    )
> >
>
>
> ---------------------------(end of
> broadcast)---------------------------
> TIP 5: Have you checked our extensive FAQ?
>
> http://www.postgresql.org/users-lounge/docs/faq.html
>