I have recently decided to wind down my blogging on here and have opted to move my blog to www.beeii.com
All the current content has been moved over and in future all new content will be added to the new site. Head over and have a look.
Everything and anything related to Business Intelligence and Microsoft SQL Server
I have recently decided to wind down my blogging on here and have opted to move my blog to www.beeii.com
All the current content has been moved over and in future all new content will be added to the new site. Head over and have a look.
This morning I saw a SQL Server Central article about the ISNUMERIC function in SQL Server and the fact that it does not always behave the way that people expect it to behave. This reminded me about the first time that I used it and was also surprised when my conversions in my scripts failed after using ISNUMERIC to test for what I believe would be values that would successfully convert to DECIMAL or NUMERIC data types.
As my experience was during some ETL work I promptly decided to use SSIS and a script task in which I could use the VB.NET Isnumeric() function that provided the desired result.
However what would you do if you need this functionality in your stored procs or TSQL scripts. One solution is to create the function that is shown at the end of the article, the other solution would be to use a CLR function written in C#.
The CLR function is really simple to write and the function itself consists mainly of the lines below.
public static SqlBoolean IsDecimal(SqlString Value)
{
decimal decValue;if (decimal.TryParse(Convert.ToString(Value), out decValue))
{
return new SqlBoolean(true);
}
else
{
return new SqlBoolean(false);
}
}
The function will use the TryParse method of the decimal type. After deploying the function I ran a test using the same SELECT statements used in the article to make sure that the CLR function returns the desired result.
Modified SQL statements:
The results were spot on with the behaviour I was looking to achieve:
| Ascii Code | Ascii Character | ISNUMERIC Returns | IsDecimal Returns |
| 9 | 1 | 0 | |
| 10 | 1 | 0 | |
| 11 | 1 | 0 | |
| 12 | 1 | 0 | |
| 13 | 1 | 0 | |
| 36 | $ | 1 | 0 |
| 43 | + | 1 | 0 |
| 44 | , | 1 | 0 |
| 45 | - | 1 | 0 |
| 46 | . | 1 | 0 |
| 48 | 0 | 1 | 1 |
| 49 | 1 | 1 | 1 |
| 50 | 2 | 1 | 1 |
| 51 | 3 | 1 | 1 |
| 52 | 4 | 1 | 1 |
| 53 | 5 | 1 | 1 |
| 54 | 6 | 1 | 1 |
| 55 | 7 | 1 | 1 |
| 56 | 8 | 1 | 1 |
| 57 | 9 | 1 | 1 |
| 92 | \ | 1 | 0 |
| 128 | € | 1 | 0 |
| 160 | 1 | 0 | |
| 162 | ¢ | 1 | 0 |
| 163 | £ | 1 | 0 |
| 164 | ¤ | 1 | 0 |
| 165 | ¥ | 1 | 0 |
The function also worked great for the last two SELECT statements in the above modified code.
If you want to grab a copy of the CLR Project you can download it here.
C:\Test\Upload\DummyFile.csv
RIGHT(@[User::strFilename],(LEN(@[User::strFilename]) - FINDSTRING(REVERSE((DT_WSTR,50)@[User::strFilename]),"\\",1) -1))