SQL Server ISNUMERIC() Clarification

非 Y 不嫁゛ 提交于 2019-12-08 07:37:40

问题


I have a table X with a list of accountNo's. This field(accoutNo) is a nvarchar(8). Now issue here is sometimes we get characters in this field as well and I want to convert it into bigint.

Sorry I'am not able to put this in a table format here.

I'am able to check if a accountNo is a numeric value or not:

select x.accountNo from x where ISNUMERIC(x.accountNo)=1

but when I try to only convert the values if an accountNo is numeric, I still can't, I'm confused:

select x.accountNo, convert(bigint,x.accountNo) from x where ISNUMERIC(x.accountNo)=1

The specific error I'm receiving:

Msg 8114, Level 16, State 5, Line 1 Error converting data type nvarchar to bigint.

Sample Data

accountNo  A0001001  A0001002  A0001003  /0005856  !0005046  ~0005872     A.005698 A/005623 A./00578 ./214536

回答1:


You should use CAST() or TRY_CAST() instead:

declare @test nvarchar(8) = '12345678'
select cast(@test as bigint) -- errors on failure
select try_cast(@test as bigint) -- returns null on failure

Also, important to point out the ISNUMERIC() isn't perfect. From the docs:

ISNUMERIC returns 1 for some characters that are not numbers, such as plus (+), minus (-), and valid currency symbols such as the dollar sign ($). For a complete list of currency symbols, see money and smallmoney (Transact-SQL).

For this reason I don't think the logical check is of value here. Best to use TRY_CAST() on all values, regardless of the presence of characters and handle the null response in a predictable manner.




回答2:


This is an issue I come across frequently. The reason you are getting the error has to do with the order in which the Query Engine is parsing the query. Essentially it is trying to do the convert before the filter.

As mentioned in pim's answer, you can resolve this by using a try_cast, or if you are using an earlier version of SQL server you can wrap a case statement around it:

select CASE WHEN ISNUMERIC(@test) = 1 THEN CONVERT(bigint, @test) ELSE 0 END



回答3:


I tried below query and did not get error. I tested on SQL 2012 and 2014.

with c as (
    select 'A0001001' as acc union all
    select 'A0001002' as acc union all
    select 'A0001003' as acc union all
    select '/0005856' as acc union all
    select '!0005046' as acc union all
    select '~0005872' as acc union all
    select 'A.005698' as acc union all
    select 'A/005623' as acc union all
    select 'A./00578' as acc union all
    select './214536' as acc
)
select isnumeric(acc), convert(bigint, acc)
from c
where isnumeric(acc) = 1

Please try this on your database to see if you get any error or not.

This should be a comment but it's too long to add into comment. Hope it helps you figure out your issue.



来源:https://stackoverflow.com/questions/47212000/sql-server-isnumeric-clarification

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!