简体   繁体   English

将大长度的 nvarchar 转换为 int

[英]convert nvarchar of large length to int

SELECT acctcode 
FROM oact 
WHERE acctcode 
BETWEEN 42100000 AND 42100001;

when I run the above query I get an error :当我运行上述查询时,出现错误:

The conversion of the nvarchar value '100000000000000' overflowed an int column. nvarchar 值 '1000000000000000' 的转换溢出了 int 列。

acctcode is nvarchar type. acctcode 是 nvarchar 类型。 I have tried:我试过了:

SELECT convert(bigint,Acctcode) as id 
FROM OACT 
WHERE acctcode 
BETWEEN 42100000 and 42100001;

It gives error :它给出了错误:

The conversion of the nvarchar value '100000000000000' overflowed an int column. nvarchar 值 '1000000000000000' 的转换溢出了 int 列。

Please help!!请帮忙!!

It's caused by the implicit conversion of the VARCHAR column in the WHERE clause.这是由 WHERE 子句中 VARCHAR 列的隐式转换引起的。

The string '100000000000000' is to big for a normal INT.字符串 '100000000000000' 对于普通的 INT 来说太大了。

So look for the strings.所以寻找字符串。

select convert(bigint,Acctcode) as id 
from OACT 
where acctcode between '42100000' and '42100001'
  and len(acctcode) = 8;

This will look for acctcode's that are alphabetically in that range.这将查找在该范围内按字母顺序排列的 acctcode。
But it'll work fine for numbers.但它适用于数字。
(assuming that the acctcode's don't have leading spaces) (假设 acctcode 没有前导空格)

Another way is to use TRY_CONVERT , if your Sql Server version supports it.另一种方法是使用TRY_CONVERT ,如果您的 Sql Server 版本支持它。

select Acctcode as id 
from OACT 
where TRY_CONVERT(INT, acctcode) between 42100000 and 42100001;

A TRY_CONVERT returns NULL when the conversion fails, instead of error.当转换失败而不是错误时, TRY_CONVERT返回 NULL。
So this wouldn't even raise errors on acctcode's that contain letters.所以这甚至不会在包含字母的 acctcode 上引发错误。

But such function is often non- Sargable .但是这样的函数通常是非Sargable 的
So this method could be slower if acctcode is indexed, and the query would ignore that index.因此,如果将 acctcode 编入索引,则此方法可能会更慢,并且查询将忽略该索引。

In your second query convert to bigint would happen only after the values are selected, but before that they are implicitly converted to int by where clause giving you the error.在您的第二个查询中,转换为 bigint 只会在选择值之后发生,但在此之前,它们会被 where 子句隐式转换为 int 给您错误。 Try this instead:试试这个:

select Acctcode from OACT where cast(acctcode as bigint) between 42100000 and 42100001;

Considering the data choice, and that you have a very small range of values ( BETWEEN 42100000 AND 42100001 ) you would be better off simply using an IN , and passing the correct data type, so that it's SARGable:考虑到数据选择,并且您的值范围非常小( BETWEEN 42100000 AND 42100001 ),您最好只使用IN并传递正确的数据类型,以便它是 SARGable:

SELECT acctcode 
FROM oact 
WHERE acctcode IN (N'42100000',N'42100001');

If you are parametrising this, I suggest using a user-defined table type, and using that.如果您对此进行参数化,我建议使用用户定义的表类型,并使用它。

I strongly recommend against using BETWEEN with nvarchar values here, as if you had something like WHERE acctcode BETWEEN N'499997' AND N'500001' then a value like N'5' would be returned.我强烈建议不要使用BETWEENnvarchar位置值,如果你有这样的事情WHERE acctcode BETWEEN N'499997' AND N'500001'然后像一个值N'5'将返回。

Using something like CONVERT (or TRY_CONVERT ) wrapped around the column ( acctcode ) would cause SARGability problems, as a full scan would be required.使用像CONVERT (或TRY_CONVERT )这样的东西包裹在列( acctcode )周围会导致 SARGability 问题,因为需要完整扫描。 Considering you have values like N'100000000000000' , this suggests a large number of rows, which would be some awful performance.考虑到你有像N'100000000000000'这样的值,这表明有大量的行,这将是一些糟糕的表现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM