在C#中,我们有unchecked
来禁用对整数运算的溢出检查
int int1;
unchecked
{
int1 = 2147483647 + 10;
}
整数运算结果将换行到-2,147,483,639
但是在T-SQL中我找不到禁用边界检查的方法
DECLARE @INT1 INT
SET @INT1 = 2147483647 + 10
导致错误:
Msg 8115,Level 16,State 2,Line 2
将表达式转换为数据类型int的算术溢出错误。
答案 0 :(得分:0)
不是我认为这一定是一个好主意,但你可以把它包装在try / catch中。
declare @int int;
begin try
set @int = 2147483647 + 10
end try
begin catch
if ERROR_NUMBER() = 8115
set @int = 2147483647
else
select
ERROR_NUMBER() AS ErrorNumber
,ERROR_MESSAGE() AS ErrorMessage;
end catch
select @int
结果:
2147483647
答案 1 :(得分:0)
根据Microsoft specification,由于INT数据类型的范围从-2,147,483,648到2,147,483,647,因此无法执行该操作(2147483647 + 10)。
相反,您可以使用BIGINT数据类型,如下所示:
DECLARE @number BIGINT;
SET @number = CAST(2147483647 AS BIGINT) + 10;
SELECT @number;
-- Output: 2147483657, as expected
答案 2 :(得分:0)
您可以将int
值转换为bigint
,执行添加,然后处理溢出,同时使用int
表达式转换回case
:
declare @MaxInt as BigInt = Power( Cast( 2 as BigInt ), 31 ) - 1;
declare @Foo as Int = 2147483647;
declare @Bar as Int = 10;
declare @BigSum as BigInt;
set @BigSum = @Foo + Cast( 10 as BigInt );
select @MaxInt as MaxInt, @Foo as Foo, @Bar as Bar, @BigSum as BigSum,
case when @BigSum <= @MaxInt then Cast( @BigSum as Int ) else
Cast( @BigSum - Power( Cast( 2 as BigInt ), 32 ) as Int ) end as Unsigned;
更新:一个更整洁的示例,说明如何获取BigInt
结果(来自先前的计算)并将其转换为Int
而不会溢出:
declare @Samples as Table ( Value BigInt );
insert into @Samples ( Value ) values
-- NB: At least one literal value needs to be cast as a BigInt to get BigInt values. No, really.
( Cast( 0x0 as BigInt ) ), ( 0x1 ), ( 0x7FFFFFFF ), ( 0x80000000 ), ( 0x80000001 ), ( 0xFFFFFFFF ),
( -1 ), ( 0x4200000001 ), ( 0x7080000000 ); -- Some BigInt values beyond 32 bits.
select Value, Cast( Value as Binary(8) ) as ValueHex,
Value & 0xFFFFFFFF as LSB32, Cast( Value & 0xFFFFFFFF as Binary(8) ) as LSB32Hex,
Cast( case when Value & 0x80000000 = 0 then Value & 0xFFFFFFFF else
( Value & 0x7FFFFFFF ) - Cast( 0x80000000 as BigInt ) end as Int ) as IntResult
from @Samples;
转换可以捆绑到UDF中,但性能可能会受到影响。