You don't happen to be able to use SQL 2012 do you? If so there are some new parse functions that you could use to make life simpler. If not then you could use the LEN function in combination with a LIKE clause to get the values you want. You might also be able to use the ISDATE function. But, the ISNUMERIC function probably will not work. Here is an example of the differences between ISNUMERIC and a numeric LIKE predicate:DECLARE @Foo TABLE (Val VARCHAR(50))INSERT @Foo (Val)VALUES('1'),('1,000'),('5e3'),('100'),('100.00'),('9781297'),('9781e297'),('978w1297'),('asdfg'),('.9781297'),('12d3'),('$123,456.00'),(' 12 '),(char(10)),('$'),(NULL)SELECT Val ,ISNUMERIC(Val) AS IsValNumeric ,CASE WHEN Val NOT LIKE '%[^0-9]%' THEN 1 ELSE 0 END AS IsIntFROM @Foo
FOr your specific code, here is something that might work. However, you may still run into issues with when SQL applies teh conversion versus when it applies teh predicate:DECLARE @testdata TABLE(data nvarchar(20) NULL)Insert into @testdataselect '20121017'UNION allselect '20121015'UNION allselect '20121016'UNION allselect 'zxdf'UNION allselect 'a'SELECT dataFROM @testdataWHERE LEN(data) <> 8OR data LIKE '%[^0-9]%'-- ORSELECT dataFROM @testdataWHERE ISDATE(data) = 0SELECT CAST(data AS DATETIME)FROM @testdataWHERE LEN(data) = 8AND data NOT LIKE '%[^0-9]%'-- OrSELECT CAST(data AS DATETIME)FROM @testdataWHERE ISDATE(data) = 1
EDIT: I was showing how to get only the dates, changed to show invalid date values