使用顺序整数更新表

时间:2012-04-28 17:19:49

标签: sql-server-2008 tsql sql-update

我继承了一个公司数据库,该公司数据库将订单号作为GUID发出。当您想引用您的订单号时,不完全是用户友好的!所以我想要做的是添加一个新的int列,并为每个现有订单添加一个唯一的顺序订单号(按日期时间排序)。

这是一个好主意,但我仍然坚持如何将其作为更新查询实际执行!任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:5)

在您的桌子上添加identity column,编号将为您完成。

alter table YourTable add YourTableID int identity

答案 1 :(得分:3)

单向。

alter table t add order_id int identity

这将添加一个自动递增的int标识列。无法保证将ID分配给现有行的顺序,但将为每个现有行分配唯一ID。此更改后插入的每个新行都将获得一个新的唯一ID。

在将其应用于实际应用程序之前,请考虑现有代码是否适用于标识列。通常这种方法是一种非常无害的升级。尝试插入标识列的代码失败,除非它使用set identity_insert。如果不删除列,则无法删除标识属性。

要解决这个问题,可能需要对新ID进行唯一约束,既可以检索速度,也可以在更新id列时强制执行唯一性。

答案 2 :(得分:2)

不幸的是,如果您只是向表中添加IDENTITY列,则现有订单不一定会按OrderDate的顺序获取IDENTITY值,因此如果您想基于订单ID值分配,它们将“无序”在订单日期(这似乎合乎逻辑)。快速举例:

CREATE TABLE dbo.Orders
(
    OrderGUID UNIQUEIDENTIFIER DEFAULT NEWID() PRIMARY KEY,
    OrderDate DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);

INSERT dbo.Orders(OrderDate) VALUES
('20120101'), ('20120102'), ('20120103');
GO

ALTER TABLE dbo.Orders ADD OrderID INT IDENTITY(1,1);
GO
SELECT OrderID, OrderGUID, OrderDate = CONVERT(DATE, OrderDate) 
FROM dbo.Orders 
ORDER BY OrderDate;

结果(显然你的不同):

OrderID OrderGUID                            OrderDate
------- ------------------------------------ ----------
2       C5CE909E-0469-45AE-A828-647C7F54AA14 2012-01-01
1       70D8EEB1-FDA8-4E56-874F-771999C6DB84 2012-01-02
3       8E7B42C3-6C4D-4860-8A82-AFADDBA96A4A 2012-01-03

如果这是不可接受的,你应该创建一个新表并将所有旧订单插入其中(此时你也可以删除我在评论中提到的GUID列。)

CREATE TABLE dbo.OrdersCopy
(
  OrderID INT IDENTITY(1,1) PRIMARY KEY,
  ... other columns ...
);

INSERT dbo.OrdersCopy (OrderDate, ... other columns ...)
SELECT OrderDate, ... other columns ...
FROM dbo.Orders 
ORDER BY OrderDate
OPTION (MAXDOP 1); -- single-threaded is important!

EXEC sp_rename 'dbo.Orders', 'OrdersOld', 'OBJECT';
EXEC sp_rename 'dbo.OrdersCopy', 'Orders', 'OBJECT';

(如果你想保留旧的GUID作为参考,暂时,当你清理其他表时,这可能没问题,但你不应该让它自动填充,你应该计划删除它,因为它很宽多余的。)