Does anyone know a good method for checking case sensitive user input using the control forms?
I would like to use Control forms to validate whether a user has entered at least one uppercase and one lowercase character, this is for validating password requirements.
By default SQL is case-insensitive. A common workaround is using:
COLLATE SQL_Latin1_General_CP1_CS_AS
I have tried to implement this but it does not seem to be working. Am I doing something wrong? Or is there another method available for implementing case sensitive comparisons?
My implementation
Best answer by Mark Jongeling
Hi Emiel,
After checking myself, I notice the collation you use does not work for this purpose. I tried this:
Both if statements should be False
For another purpose, cleaning table names, I have used the ASCII() function. It could also work for this. I rebuilded it a little for you. You can them make the changes needed to return the correct error(s).
declare @password varchar(256) = 'password'
select @password = trim(@password)
declare @length int = len(@password)
, @counter int = 1
, @correct int = 1
, @ascii_code int
--Go through the password, one by one character
while @counter <= @length
and @correct = 1begin
--Make a ASCII code of the string
select @ascii_code = ascii(substring(@password, @counter, 1))
--What is allowed
if @ascii_code between 48and57or --Numbers
@ascii_code between 65and90or --Uppercase letters
@ascii_code between 97and122or --Lowercase letters
@ascii_code = 95 --Underscore
begin
--Up the counter
select @counter = @counter + 1endelsebeginselect @correct = 0 --Password incorrect
endendif @correct = 1beginselect'Correct'endelsebeginselect'Incorrect'end
After checking myself, I notice the collation you use does not work for this purpose. I tried this:
Both if statements should be False
For another purpose, cleaning table names, I have used the ASCII() function. It could also work for this. I rebuilded it a little for you. You can them make the changes needed to return the correct error(s).
declare @password varchar(256) = 'password'
select @password = trim(@password)
declare @length int = len(@password)
, @counter int = 1
, @correct int = 1
, @ascii_code int
--Go through the password, one by one character
while @counter <= @length
and @correct = 1begin
--Make a ASCII code of the string
select @ascii_code = ascii(substring(@password, @counter, 1))
--What is allowed
if @ascii_code between 48and57or --Numbers
@ascii_code between 65and90or --Uppercase letters
@ascii_code between 97and122or --Lowercase letters
@ascii_code = 95 --Underscore
begin
--Up the counter
select @counter = @counter + 1endelsebeginselect @correct = 0 --Password incorrect
endendif @correct = 1beginselect'Correct'endelsebeginselect'Incorrect'end
To add to Mark’s answer, the reason it doesn’t work is because of the [A-Z] range in your LIKE comparison. These ranges appear to always be case-insensitive, but it does work if you write out the letters of the range.
Try out the following two queries and see how their results differ:
It's important to note that the _AS part of this collation indicates that it is accent-sensitive. This means that é will not match e and therefore a password like ÀàààÉééé will not match either of your LIKE-comparisons, causing the password to be rejected. You might want to consider the Latin1_General_CS_AI collation instead.
We use 3 different kinds of cookies. You can choose which cookies you want to accept. We need basic cookies to make this site work, therefore these are the minimum you can select. Learn more about our cookies.