首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server BIGINT 轉 INT 符號位溢出問題的通用解決函數

     編輯:關於SqlServer

場景:使用位運算在 INT 儲存多狀態(正常/警告/異常),彙總時需 BIGINT 運算避免溢位,轉回 INT 時遇算術溢出錯誤(訊息 8115),原因是最高位 0x80000000 被視為符號位。

根因分析

  • INT 範圍:-2,147,483,648 ~ 2,147,483,647(最高位為符號位)。
  • 位運算使用 0x80000000 代表某狀態,對應 INT 最小值 -2,147,483,648。
  • BIGINT 運算結果含此位,直接 CAST/CONVERT 到 INT 視為負數溢位。

解決函數:位級轉換保持位模式不變

CREATE FUNCTION [dbo].[BigintToInt] (@Value BIGINT)
RETURNS INT
AS
BEGIN
    -- 若最高位(符號位)為 1,視為負數,需符號擴展
    IF @Value & 0x80000000 <> 0
        RETURN @Value & 0xFFFFFFFF | 0xFFFFFFFF00000000;
    -- 最高位為 0,直接截取低 32 位
    RETURN @Value & 0xFFFFFFFF;
END

運作原理

  • @Value & 0x80000000:檢測第 31 位(符號位)是否為 1。
  • 若為 1:@Value & 0xFFFFFFFF 取低 32 位,再 | 0xFFFFFFFF00000000 進行符號擴展,得到正確的負數 INT。
  • 若為 0:直接取低 32 位,結果為正數。

使用範例

DECLARE @b BIGINT = 0x80000000;  -- 2147483648 (超出 INT 正數範圍)
SELECT dbo.BigintToInt(@b);       -- 回傳 -2147483648 (正確的 INT 位模式)

DECLARE @b2 BIGINT = 0xFFFFFFFF;  -- 4294967295
SELECT dbo.BigintToInt(@b2);      -- 回傳 -1 (全 1 位模式)

應用場景

  • 位元旗標彙總(監控狀態、權限遮罩、功能開關)。
  • 從外部系統(Java/Redis/二進制協議)接收無符號 32 位整數寫入 SQL INT。
  • 任何需保持位模式不變的 BIGINT → INT 轉換。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved