我有一个表格X,上面有一个accountNo列表。该字段(accoutNo)是nvarchar(8)。 现在问题是我们有时会在这个字段中获得字符,我想将它转换为bigint。
很抱歉,我无法在此处以表格格式表示这一点。
我能够检查accountNo是否是数值:
select x.accountNo from x where ISNUMERIC(x.accountNo)=1
但是当我尝试仅在accountNo是数字时转换值时,我仍然不能,我很困惑:
select x.accountNo, convert(bigint,x.accountNo) from x where ISNUMERIC(x.accountNo)=1
我收到的具体错误:
Msg 8114,Level 16,State 5,Line 1转换数据类型时出错 nvarchar到bigint。
accountNo A0001001 A0001002 A0001003 /0005856 !0005046 ~0005872 A.005698 A/005623 A./00578 ./214536
答案 0 :(得分:5)
您应该使用CAST()
或TRY_CAST()
代替:
declare @test nvarchar(8) = '12345678'
select cast(@test as bigint) -- errors on failure
select try_cast(@test as bigint) -- returns null on failure
另外,重要的是指出ISNUMERIC()
并不完美。来自docs:
对于某些非数字字符,例如加号(+),减号( - )和有效货币符号(如美元符号($)),ISNUMERIC返回1。有关货币符号的完整列表,请参阅money和smallmoney(Transact-SQL)。
出于这个原因,我不认为逻辑检查在这里是有价值的。最好在所有值上使用TRY_CAST()
,无论是否存在字符,并以可预测的方式处理空响应。
答案 1 :(得分:2)
这是我经常遇到的问题。您收到错误的原因与查询引擎解析查询的顺序有关。基本上它是尝试在过滤器之前进行转换。
正如pim的回答中提到的,你可以通过使用try_cast来解决这个问题,或者如果你使用的是早期版本的SQL服务器,你可以在它周围包装一个case语句:
read -ra arrcourse < tmp2
答案 2 :(得分:1)
我在下面尝试查询并没有收到错误。我在SQL 2012和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
请在您的数据库中尝试此操作,看看是否有任何错误。
这应该是一个评论,但加入评论太长了。希望它可以帮助你弄清楚你的问题。