您可以将int 值转换为bigint,执行加法,然后处理溢出,同时使用case 表达式转换回int:
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 中。