问题
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