sql server programming:
Try: select case when 'C=' like '%[^a-zA-Z0-9!@~#$\^&*()\_+-;:",.{}]%' escape '\' then 1 else 0 end go Notice that I am escaping the characters '^' and '_', because the have a menaing when used in the right side with LIKE operator. Notice also that I rearranged the characters and pput '{}' at the end of the list, they where yielding wrong behavior in the position the were before (I do not know why?). AMB [quoted text, click to view] "Boot2TheHead" wrote: > I have a database table that should allow punctuation in one column, > but not all punctuation. I added a check constraint like so: > ([MyColName] like '%[a-zA-Z0-9!@~#$^&*()_+-{};:",.]%') > > However, it isn't working like I think it should. If I take the last % > out, the existing data in the database isn't allowed, so the table > won't save. So I put in the expression above, but the constraint > doesn't seem to fire. I put in 'C=' (= is not in the list) and it was > allowed. Seems to me that it shouldn't be allowed. I couldn't find any > documentation on how to make LIKE allow multiple characters as in > "LIKE %[(expression)]*" but I suppose that's more reg-exy. >
All you are ensuring is that one character matches your list. To demonstrate I'll use a slightly simpler expression: SELECT CASE WHEN 'C=' LIKE '%[A-Z]%' THEN 1 ELSE 0 END, CASE WHEN '=C' LIKE '%[A-Z]%' THEN 1 ELSE 0 END, CASE WHEN '=' LIKE '%[A-Z]%' THEN 1 ELSE 0 END; -- this is the only one that fails Remember that ^ (not) is a special character in this case and you don't want to blindly slide it in here. You are much better off building a list of characters that are NOT allowed and then your check constraint can be like (I think): CHECK myCol NOT LIKE '%[=/]%' -- Aaron Bertrand SQL Server MVP http://www.sqlblog.com/ http://www.aspfaq.com/5006 [quoted text, click to view] "Boot2TheHead" <jcollum@gmail.com> wrote in message news:1182452919.658298.288390@z28g2000prd.googlegroups.com... >I have a database table that should allow punctuation in one column, > but not all punctuation. I added a check constraint like so: > ([MyColName] like '%[a-zA-Z0-9!@~#$^&*()_+-{};:",.]%') > > However, it isn't working like I think it should. If I take the last % > out, the existing data in the database isn't allowed, so the table > won't save. So I put in the expression above, but the constraint > doesn't seem to fire. I put in 'C=' (= is not in the list) and it was > allowed. Seems to me that it shouldn't be allowed. I couldn't find any > documentation on how to make LIKE allow multiple characters as in > "LIKE %[(expression)]*" but I suppose that's more reg-exy. >
[quoted text, click to view] > rearranged the characters and pput '{}' at the end of the list, they where > yielding wrong behavior in the position the were before (I do not know > why?).
Because there was a dash, so +-{ was probably interpreted as RANGE: "+" -> "{" -- Aaron Bertrand SQL Server MVP http://www.sqlblog.com/ http://www.aspfaq.com/5006
[quoted text, click to view] > If I only wanted A-Z I'd have a list that's 256-26=230 characters.
But you want to allow A-Z, a-z, 0-9, plus at least 20 others. Plus a large portion of those 256 characters are non-printing (e.g. CHAR(9), CHAR(10), CHAR(13)), and you haven't said anything about spaces or characters with accents. Which characters, exactly, out of the 256, do you NOT want to allow? I still think that will be the shorter of the two lists, and FAR less than 230. -- Aaron Bertrand SQL Server MVP http://www.sqlblog.com/ http://www.aspfaq.com/5006
Why are you saying LIKE '%[^a-z...]%' Once again, you realize that ^ means NOT? So you want to return allcharsallowed = 1 when the string does NOT contain a-z? -- Aaron Bertrand SQL Server MVP http://www.sqlblog.com/ http://www.aspfaq.com/5006 [quoted text, click to view] "Boot2TheHead" <jcollum@gmail.com> wrote in message news:1182458687.885569.172340@i38g2000prf.googlegroups.com... > Well, I don't think it's working. I used this function: > > DECLARE @allCharsAllowed int > > set @allCharsAllowed = ( Select > case > when @stringToCheck like '%[^a-zA-Z0-9!@~#$\^&*()\_+-;:",.{}]%' > escape '\' then 1 > else 0 > end ) > > -- Return the result of the function > RETURN @allCharsAllowed > > When I passed in [ and ' and < I got a 0 back. Good. But passing in [a > returned a 1. Maybe I need to check that the count of all characters > matching the chars in the list is the same as the length of the > string. I'm a C# programmer here, so I think in loops and SQL does > not, so I tend to think in the wrong direction. > > This seems like a lot of work for a validator. Should I just switch to > a regex? >
[quoted text, click to view] > A non printing character getting into my database broke my app this > morning (well it just stopped returning results). So those are in the > list of things that I don't want to allow. 26 + 26 + 10 + 20 is 82, so > there are 174 ASCII chars that are on the "not allowed" list.
Did you ignore half of what I said? Or are you saying you won't allow words like résumé or naïve? I was just suggesting an alternative approach : return 1 because you didn't find a bad character, not because you have determined that all characters are good. Have you considered validating the input in C# (where you can do regex in one line) instead of (or, better yet, in addition to) the basic stuff that is easy in the database? A
I have a database table that should allow punctuation in one column, but not all punctuation. I added a check constraint like so: ([MyColName] like '%[a-zA-Z0-9!@~#$^&*()_+-{};:",.]%') However, it isn't working like I think it should. If I take the last % out, the existing data in the database isn't allowed, so the table won't save. So I put in the expression above, but the constraint doesn't seem to fire. I put in 'C=' (= is not in the list) and it was allowed. Seems to me that it shouldn't be allowed. I couldn't find any documentation on how to make LIKE allow multiple characters as in "LIKE %[(expression)]*" but I suppose that's more reg-exy.
Thanks Aaron. I didn't even notice the ^ in there. I'll have to escape that. The list of characters that are not allowed is quite large isn't it? If I only wanted A-Z I'd have a list that's 256-26=230 characters. This looks like it needs a regular expression but I'm afraid that would slow things down in a big way. Must be a better way. It's looking like I'm gonna have to write a function that gets the int value of every character in a string and checks that against a list of disallowed character-numbers. Ugh. On Jun 21, 12:46 pm, "Aaron Bertrand [SQL Server MVP]" [quoted text, click to view] <ten....@dnartreb.noraa> wrote: > All you are ensuring is that one character matches your list. To > demonstrate I'll use a slightly simpler expression: > > SELECT > CASE WHEN 'C=' LIKE '%[A-Z]%' THEN 1 ELSE 0 END, > CASE WHEN '=C' LIKE '%[A-Z]%' THEN 1 ELSE 0 END, > CASE WHEN '=' LIKE '%[A-Z]%' THEN 1 ELSE 0 END; -- this is the only one that > fails > > Remember that ^ (not) is a special character in this case and you don't want > to blindly slide it in here. You are much better off building a list of > characters that are NOT allowed and then your check constraint can be like > (I think): > > CHECK myCol NOT LIKE '%[=/]%' > > -- > Aaron Bertrand > SQL Server MVP http://www.sqlblog.com/http:// www.aspfaq.com/5006
Well, I don't think it's working. I used this function: DECLARE @allCharsAllowed int set @allCharsAllowed = ( Select case when @stringToCheck like '%[^a-zA-Z0-9!@~#$\^&*()\_+-;:",.{}]%' escape '\' then 1 else 0 end ) -- Return the result of the function RETURN @allCharsAllowed When I passed in [ and ' and < I got a 0 back. Good. But passing in [a returned a 1. Maybe I need to check that the count of all characters matching the chars in the list is the same as the length of the string. I'm a C# programmer here, so I think in loops and SQL does not, so I tend to think in the wrong direction. This seems like a lot of work for a validator. Should I just switch to a regex?
On Jun 21, 1:37 pm, "Aaron Bertrand [SQL Server MVP]" [quoted text, click to view] <ten....@dnartreb.noraa> wrote: > Which characters, exactly, out of the 256, do you NOT want to > allow? I still think that will be the shorter of the two lists, and FAR > less than 230.
A non printing character getting into my database broke my app this morning (well it just stopped returning results). So those are in the list of things that I don't want to allow. 26 + 26 + 10 + 20 is 82, so there are 174 ASCII chars that are on the "not allowed" list. It's a larger list.
On Jun 21, 1:53 pm, "Aaron Bertrand [SQL Server MVP]" [quoted text, click to view] <ten....@dnartreb.noraa> wrote: > Why are you saying LIKE '%[^a-z...]%'
Typo. I must've cut and pasted before I finished the function.
I think I have it. I just take the LIKE statement above and walk the chars one by one. I hope someone can improve upon this. It looks like a lot of work for every insert/update to be doing. -- BEGIN FUNCTION -- Declare the return variable here DECLARE @allCharsAllowed int declare @substring varchar(1) declare @position int set @allCharsAllowed = 1 set @position = 1 -- while each char is in the allowed list, look at each character while @allCharsAllowed <> 0 AND @position < len(@stringToCheck) begin -- get substring set @substring = (substring(@stringToCheck , @position, 1)) -- check the substring set @allCharsAllowed = ( Select case when @substring like '%[a-zA-Z0-9!@~#$\^&*()\_+\-;:",.\{\}]%' escape '\' then 1 else 0 end ) -- move to next set @position = @position + 1 end -- returns 0 if any illegal chars are found RETURN @allCharsAllowed -- END
Almost. The inner loop should be: while @allCharsAllowed <> 0 AND @position < (len(@stringToCheck) +1) begin -- get substring set @substring = (substring(@stringToCheck , @position, 1)) print @substring -- check the substring set @allCharsAllowed = ( Select case when @substring like '%[a-zA-Z0-9!@~#$\^&*()\_+\-;:",.\{\}]' escape '\' then 1 else 0 end ) -- move to next set @position = @position + 1 end
Hi Aaron, Good catch. I guess we should escape also the minus sign in this case. select case when 'C=' like '%[^a-zA-Z0-9!@~#$\^&*()\_+\-{};:",.]%' escape '\' then 1 else 0 end go Thanks, Alejandro Mesa [quoted text, click to view] "Aaron Bertrand [SQL Server MVP]" wrote: > > rearranged the characters and pput '{}' at the end of the list, they where > > yielding wrong behavior in the position the were before (I do not know > > why?). > > Because there was a dash, so +-{ was probably interpreted as RANGE: "+" -> > "{" > > -- > Aaron Bertrand > SQL Server MVP > http://www.sqlblog.com/ > http://www.aspfaq.com/5006 > > >
Don't see what you're looking for? Try a search.
|