Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
Transact Charlie
Master Smack Fu Yak Hacker
3451 Posts |
Posted - 2009-10-30 : 08:15:38
|
Hi All.Is the order of comparators (= <> IS ... etc) guaranteed in cases such as this:(This is an example to show the question -- I don't care about any more efficient way to do this)....DECLARE @digits INT SET @digits = 4DECLARE @foo TABLE ( [staffNumber] VARCHAR(255) )INSERT @foo ([staffNumber]) SELECT '000123'UNION SELECT '123'UNION SELECT 'x123312'UNION SELECT '1123~'UNION SELECT '000001'UNION SELECT '2131231231'SELECT 'PROBLEM CASE' AS [Validation] , [staffNumber]FROM @fooWHERE LEN([staffNumber]) <> @digits AND ( [staffNumber] LIKE '%[^0123456789]%' OR CAST([staffNumber] AS INT) <> CAST(RIGHT([staffNUmber], @digits) AS INT) ) Here I want to find any [staffNumber] That could not be justified to 4 places -- (so either adding 0's or removing 0's from the set as long as the meaning of the [staffNumber] is retained.Am I right in thinking that1) The LEN([staffNumber]) <> @digits is checked first -- only if it passes this then the next comparison is done?2) As above inside the () The check for non numerals is checked before the CAST?If it isn't in some circumstance (if the CAST is ever done first) then some of the [staffNumber] rows will throw an error (they can't be converted to INT because of the non numeral characters).This sql works in my testing but I need to know if I can rely on this behaviour or if, in some circumstance, the order of comparison will not be guaranteed.Cheers.Charlie.Charlie===============================================================Msg 3903, Level 16, State 1, Line 1736The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION |
|
|
russell
Pyro-ma-ni-yak
5072 Posts |
Posted - 2009-10-30 : 09:03:59
|
| no, you can not rely on this.http://blogs.msdn.com/sqlprogrammability/archive/2006/05/12/596401.aspx |
 |
|
|
Transact Charlie
Master Smack Fu Yak Hacker
3451 Posts |
Posted - 2009-10-30 : 09:33:53
|
Cheers. I kinda suspected not.I like this comment from the link:quote: # re: Predicate ordering is not guaranteedOr, better, how about designing tables with properly typed columns so as to avoid bad data issues to begin with? Friday, May 19, 2006 4:24 PM by AdamMachanic
Properly typed columns when the database was designed by java programmers? A man can dream. A man can dream.....[NB]Hell, I may as well wish for some constraints as well...... sighCharlie===============================================================Msg 3903, Level 16, State 1, Line 1736The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION |
 |
|
|
russell
Pyro-ma-ni-yak
5072 Posts |
Posted - 2009-10-30 : 11:31:25
|
| LOL. |
 |
|
|
Michael Valentine Jones
Yak DBA Kernel (pronounced Colonel)
7020 Posts |
Posted - 2009-10-30 : 11:51:11
|
Use a CASE when tests have to be evaluated in sequence.declare @digits intset @digits = 4Select *from ( -- Test Data select staffNumber = '01234' union all select staffNumber = '00123' union all select staffNumber = '51234' union all select staffNumber = '012a4' union all select staffNumber = '1234' ) awhere 1 = case when [staffNumber] LIKE '%[^0123456789]%' then 1 when CAST([staffNumber] AS INT) <> CAST(RIGHT([staffNUmber], @digits) AS INT) then 1 else 0 end Results:staffNumber ----------- 51234012a4(2 row(s) affected) CODO ERGO SUM |
 |
|
|
parody
Posting Yak Master
111 Posts |
Posted - 2009-10-30 : 12:48:02
|
| each OR () is tested independently, I think you just need to specify only [staffNumber] LIKE '%[0123456789]%' is attempted casting -i.e. ([staffNumber] LIKE '%[0123456789]%' AND CAST([staffNumber] AS INT) <> CAST(RIGHT([staffNUmber], @digits) AS INT))alternatively tidy the data and remove any rogue characters from the string first. I just posted a way of changing groups of characters in a string to 0 here you could change it to be blanks insteadhttp://www.sqlteam.com/forums/topic.asp?TOPIC_ID=135147By the way easier way of saying '%[0123456789]%' is '%[0-9]%', '%[^0-9]%', '%[a-z]%' etc etc |
 |
|
|
|
|
|
|
|