I need to store the unsigned int equivlant of both halfs of a bigint string in two separate fields in a DB for compatibility with a 3rd part solution.
I've looked at the solution here, and it seems to work well except for the fact it often returns negative numbers. I assume this is a result of being unsigned data where SQL expected it to be signed, but I am speculating there...
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
So my question is why does the right half output sometimes return an incorrect negative value, and how do I solve that so it is always correct?
I see the same weird results for certain input numbers when doing this with .NET as well.
Dim original As Int64 = 8589934590
Dim rightHalfUnSigned As UInt32 = CType(original And &H7FFFFFFF, UInt32)
Console.writeline(rightHalfUnSigned)
Output: 2147483646
I don't understand these functions underlying mechanics well enough to know why this happens for the input number 8589934590, yet for 8589934595 it works perfectly.