【发布时间】:2015-10-13 16:35:14
【问题描述】:
为了与第 3 部分解决方案兼容,我需要将 bigint 字符串的两半的 unsigned int 等值存储在数据库的两个单独字段中。
我已经查看了这里的解决方案,它似乎运行良好,除了它经常返回负数的事实。我认为这是由于 SQL 期望它被签名的未签名数据的结果,但我推测那里......
SQL - safely downcast BIGINT to INT
DECLARE @BigintDataLimitIn BIGINT = 8589934590;
DECLARE @RightHalf INT, @LeftHalf INT;
WITH v AS (SELECT CAST(@BigintDataLimitIn AS varbinary) AS bin)
SELECT
@LeftHalf = SUBSTRING(bin, 1, 4),
@RightHalf = SUBSTRING(bin, 5, 4)
FROM v;
SELECT @LeftHalf, @RightHalf
----------------------------------------
(LeftHalf) (RightHalf)
1 -2
所以我的问题是为什么右半边输出有时会返回不正确的负值,我该如何解决它才能始终正确?
当使用 .NET 执行此操作时,对于某些输入数字,我也看到了同样奇怪的结果。
Dim original As Int64 = 8589934590
Dim rightHalfUnSigned As UInt32 = CType(original And &H7FFFFFFF, UInt32)
Console.writeline(rightHalfUnSigned)
Output: 2147483646
我对这些函数的基础机制了解得不够透彻,无法知道为什么输入数字 8589934590 会发生这种情况,但对于 8589934595 来说却完美无缺。
【问题讨论】:
-
向我们展示导致问题的数据样本,该样本的预期结果也会很好。
-
正确输出:BIGINT = 8589934595 LeftHalf RightHalf RawBinary 2 3 0x0000000200000003 输出不正确:BIGINT = 8589934590 LeftHalf RightHalf RawBinary 2 -2 0x00000001FFFFFFFE
标签: sql-server