将INT转换为无符号INT

时间:2015-07-06 22:56:25

标签: ssis sql-server-2012 msbi

我在prod中有一个大型表,INT数据类型,它是主键和标识列(1,1)。行数是2147479257。 在每日作业运行期间,ETL由于算术溢出错误而失败,因为它不能再适应目标表中的任何行。

请问如何将列更改为 unsigned int。

2 个答案:

答案 0 :(得分:0)

将数据类型更改为bigint

bigint -2^63 (-9,223,372,036,854,775,808) to 2^63-1 (9,223,372,036,854,775,807)

答案 1 :(得分:0)

你已经溢出了一个int,这意味着你在表中有大约2B行。通过切换到unsigned int,您希望获得另外20亿行可寻址空间。这种方法的问题是SQL Server不支持unsigned int作为数据类型。

你的直觉反应可能是为了达到Greg改变bigint数据类型的方法。这种方法面临的挑战是,当你的处理在水中死亡时,你需要快速修复并更改为bigint,该表的任何其他消费者现在都将失败。顺便说一句,我在2011年经历过这个。我们修复数据库只是为了让所有报告和.NET应用程序都失败。在那项工作中,将我们的处理排队等待N天的情况远远不是灾难性的,而我们给出了正常的外观,而不是通过让每个面向外部的应用程序都失败来消除所有疑问。

通过标识列的一般实现,您可以轻松获得另一个2B,而无需更改单个代码 - 只需将标识值设置为下限,并且您已经为自己买了足够的时间来计划迁移到bigint。对此的命令是dbcc checkident

您还可能希望确保将标识列指定为唯一值。人们经常将标识列设置为主键,否则,您将运行与以下类似的代码。

SET NOCOUNT ON;

IF EXISTS
(
    SELECT * FROM sys.tables AS T INNER JOIN sys.schemas AS S ON S.schema_id = T.schema_id WHERE S.name = 'dbo' AND T.name = 'IntOverfloweth'
)
BEGIN

    DROP TABLE 
        dbo.IntOverfloweth;
END

CREATE TABLE 
    dbo.IntOverfloweth
(
    IntOverflowethID int IDENTITY(2147483647,1) NOT NULL
,   SomeValue varchar(30)
);

INSERT INTO
    dbo.IntOverfloweth
(SomeValue)
OUTPUT
    Inserted.*
VALUES
('Before');


BEGIN TRY

    INSERT INTO
        dbo.IntOverfloweth
    (SomeValue)
    OUTPUT
        Inserted.*
    VALUES
    ('Overflow');

END TRY
BEGIN CATCH
    SELECT ERROR_MESSAGE() AS ErrorMessage;
END CATCH

-- Push the pointer back around to the begining 
DBCC CHECKIDENT('dbo.IntOverfloweth', RESEED, -2147483648);

-- Ensure uniqueness
CREATE UNIQUE INDEX UQ_IntOverfloweth
    ON dbo.IntOverfloweth
(
    IntOverflowethID
);

INSERT INTO
    dbo.IntOverfloweth
(SomeValue)
OUTPUT
    Inserted.*
VALUES
('Does not Overflow');