I have a database with an email field, and it cycles through the database to grab all the transactions concerning a certain email address.
Users putting in lowercase letters when their email is stored with a couple capitals is causing it not to show their transactions. When I modify it to match perfect case with the other emails, it works.
How can I modify this so that it correctly compares with the email field and case doesn't matter? Is it going to be in changing how the email gets stored?
$result = mysql_query("SELECT * FROM `example_orders` WHERE `buyer_email`='$useremail';") or die(mysql_error());
Thanks ahead of time!
A mixed PHP/MySQL solution:
$result = mysql_query("
SELECT *
FROM example_orders
WHERE LOWER(buyer_email) = '" . strtolower($useremail) . "';
") or die(mysql_error());
What it does is converting both sides of the comparison to lowercase. This is not very efficient, because the use of LOWER
will prevent MySQL from using indexes for searching.
A more efficient, pure SQL solution:
$result = mysql_query("
SELECT *
FROM example_orders
WHERE buyer_email = '$useremail' COLLATE utf8_general_ci;
") or die(mysql_error());
In this case, we are forcing the use of a case-insensitive collation for the comparison. You wouldn't need that if the column had a case-insensitive collation in the first place.
Here is how to change the column collation, as suggested by Basti in a comment:
ALTER TABLE `example_orders`
CHANGE `buyer_email` `buyer_email` VARCHAR( 100 )
CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL
If you choose to do that, you can run the query without COLLATE utf8_general_ci
.
COLLATE
bfavaretto 2012-04-04 21:44
buyer_email
to use this collation per default. :- - Basti 2012-04-04 21:45
bob@example.com
and Bob@example.com
are two different email addresses according to RFC 2821. But most email providers won't allow this anyway, so yes he should do this! ;- - Basti 2012-04-04 21:49
Uh... you realize that email addresses are case sensitive, right? From RFC 2821:
Verbs and argument values (e.g., "TO:" or "to:" in the RCPT command
and extension name keywords) are not case sensitive, with the sole
exception in this specification of a mailbox local-part (SMTP
Extensions may explicitly specify case-sensitive elements). That is, a command verb, an argument value other than a mailbox local-part,
and free form text MAY be encoded in upper case, lower case, or any
mixture of upper and lower case with no impact on its meaning. This
is NOT true of a mailbox local-part. The local-part of a mailbox
MUST BE treated as case sensitive. Therefore, SMTP implementations
MUST take care to preserve the case of mailbox local-parts. Mailbox
domains are not case sensitive. In particular, for some hosts the
user "smith" is different from the user "Smith". However, exploiting the case sensitivity of mailbox local-parts impedes interoperability
and is discouraged.
(emphasis added)
utf8_general_ci
as collation for the email column. You will be able to store the emails in their original case, but comparisons will ignore the case ("_ci" = case-insensitive). This is exactly what you wanted! :- - Basti 2012-04-04 21:52
If you do WHERE buyer_email LIKE '...'
it'll by default do a case-insensitive match.
With e-mail fields, though, I prefer to lowercase the e-mail address when I insert it into the DB.
LIKE
behaviour, as well as =
depends on the collation. They both may be case-sensitive or no - zerkms 2012-04-04 21:39
LIKE
for strict comparison instead of =
is as bad, as LOWER()
zerkms 2012-04-04 21:40