September 27, 2010 at 10:48 am
The discussion usually answer my questions but not this time. Doesn't "isnumeric(char(32)) as n" return 0? And if so wouldn't "select sum(n) from l" also equal 0? I guess I don't see how the sum of n got to 16 if n is alway 0?
Thanks, Jerry
September 27, 2010 at 11:14 am
Interesting question and great feedback from the discussion!!
Jason...AKA CirqueDeSQLeil
_______________________________________________
I have given a name to my pain...MCM SQL Server, MVP
SQL RNNR
Posting Performance Based Questions - Gail Shaw[/url]
Learn Extended Events
September 27, 2010 at 11:24 am
jlennartz (9/27/2010)
The discussion usually answer my questions but not this time. Doesn't "isnumeric(char(32)) as n" return 0? And if so wouldn't "select sum(n) from l" also equal 0? I guess I don't see how the sum of n got to 16 if n is alway 0?Thanks, Jerry
Jerry, the recursive CTE [i.e, "with l as ( .... )" ] creates a set of rows with the value being tested ranging from 32 to 127, so the code actually tests each character from char(32) (i.e, ' ') to char(127). There are sixteen characters in that range that can be convertible to one or more data types (usually money, as that type seems to have a very broad tolerance for conversion.) See my earlier post for a reference to recursive CTEs.
September 27, 2010 at 11:24 am
jlennartz (9/27/2010)
I guess I don't see how the sum of n got to 16 if n is alway 0?
Jerry, hopefully someone will post a tidy explanation of how a recursive CTE works. In the meantime, run this SQL to see the entire contents of the 'l' table:
with l as (
select 32 as i, char(32) as s, isnumeric(char(32)) as n
union all
select i+1, char(i+1), isnumeric(char(i+1)) from l where i < 127
)
select * from l
That should help you begin to understand what's going on.
September 27, 2010 at 11:29 am
jlennartz (9/27/2010)
The discussion usually answer my questions but not this time. Doesn't "isnumeric(char(32)) as n" return 0? And if so wouldn't "select sum(n) from l" also equal 0? I guess I don't see how the sum of n got to 16 if n is alway 0?
The start of the query is a "recursive CTE". It consists of an anchor query and a recursive query. The anchor query is:
select 32 as i, char(32) as s, isnumeric(char(32)) as n
This returns a single row, with columns 1 (integer value 32), s (char(1), value ' ' (the space character)), and column n (integer value 0, the result of ISNUMERIC(char(32))).
The recursive query is:
select i+1, char(i+1), isnumeric(char(i+1)) from l where i < 127
Note that the FROM clause references the CTE itself. That makes the CTE recursive. On the first iteration, the FROM denotes the reqults of the anchor query. Since i = 32 in that row, the recursive part will now produce a similar row for the value i+1 (33). But then the recursing starts. The recursive part is evaluated again, with this new row as input, so now a row is produced that starts with i = 33 and generates column values for the value 34. This continues until the WHERE clause is no longer satisfied.
[The actual execution plan will probably be more efficient than this!]
The result is a table with 96 rows, with i ranging from 32 to 127 and s and n representing char(i) and isnumeri(char(i)) for each row.
The outer query then sums those isnumeric values.
September 27, 2010 at 11:51 am
Thank You sknox, wware and especially Hugo. With Hugo's explaination it all became clear.
Thanks to all,
Jerry
September 27, 2010 at 11:53 am
jlennartz (9/27/2010)
...With Hugo's explaination it all became clear.
It generally does. 😀
September 27, 2010 at 6:00 pm
Why does select i+1, char(i+1), isnumeric(char(i+1)) from l where i < 127
need an i+1 in each column?
September 28, 2010 at 12:24 am
foxxo (9/27/2010)
Why doesselect i+1, char(i+1), isnumeric(char(i+1)) from l where i < 127
need an i+1 in each column?
If you use
select i+1, char(i), isnumeric(char(i)) from l where i < 127
Then you'd probably get the same results from the summation, but if you check the actual rows produced by the CTE, you'd see weird results. For example, when i = 80, you'd get the number 81 for the row with char(80) and isnumeric(char(80)).
September 29, 2010 at 1:25 am
78% correct answers?! Yeah, right.
Great question and good points in discussion by Hugo. Pleasure to read.
But, thanks to all who participated in it.
Hrvoje
Hrvoje Piasevoli
September 29, 2010 at 2:05 am
A good question that has taught me two things:
1. You can't trust SQL's ISNUMERIC function
2. You can build a recursive CTE - although I'm no sure I would want to 😉
If anyone else has examples of CTE's I bet they'd make for some tricky questions?
Thanks
September 29, 2010 at 3:49 am
jts_2003 (9/29/2010)
2. You can build a recursive CTE - although I'm no sure I would want to 😉
Recursive CTE'sare an invaluable tool when working with hierarchic data (like employee/supervisor relations, parts built of parts built of parts, genealogy data, etc). There are some examples of this in Books Online.
September 29, 2010 at 3:04 pm
Very nice question. And one more time I see that 'isnumeric' works in a way which is far away from our expectations. Always used custom made functions instead.
October 8, 2010 at 9:03 am
Great question! Now that I know how "liberal" is numeric is, I will be more careful with it.
Thanks!!!
Viewing 14 posts - 31 through 43 (of 43 total)
You must be logged in to reply to this topic. Login to reply