SQL Server,在两个表上按顺序重新编号int列

时间:2012-12-04 14:25:08

标签: sql sql-server tsql

我有以下两个表和数据: -

CREATE TABLE customers
    ([id] int, [name] varchar(10), [sex] varchar(1))
;

INSERT INTO customers
    ([id], [name], [sex])
VALUES
    (1050, 'John Doe', 'M'),
    (1060, 'Jane Doe', 'F'),
    (1031, 'Joe Bloggs', 'M')
;

CREATE TABLE orders
    ([id] int, [fk] int, [product] varchar(13))
;

INSERT INTO orders
    ([id], [fk], [product])
VALUES
    (51, 1050, 'Blue car'),
    (57, 1050, 'Yellow car'),
    (43, 1060, 'Pink bus'),
    (32, 1031, 'Black pen'),
    (87, 1031, 'Orange jacket')
;

我想要做的是从1开始按顺序重新编号两个表中的id列。

orders表中的链接行也必须重新编号,此表中的外键必须与customers表中的新数字匹配。

所以数据最终需要看起来像这样: -

ID      NAME        SEX
0001    John Doe    M
0002    Jane Doe    F
0003    Joe Bloggs  M

ID    FK    PRODUCT
0001  0001  Blue car
0002  0001  Yellow car
0003  0002  Pink bus
0004  0003  Black pen
0005  0003  Orange jacket

我将如何在SQL Server中执行此操作?

3 个答案:

答案 0 :(得分:6)

绝对不需要在这里诉诸游标(yikes!)....你需要这样的东西:

-- Table "Customers" - rename column "id" to "old_id"
EXEC sp_rename 'dbo.Customers.id', 'old_id'

-- add new "id" column
ALTER TABLE Customers ADD id INT 

-- fill new "id" column with sequential values, ordered by the "old_id" value
;WITH CTE AS
(
    SELECT old_id, new_id = ROW_NUMBER() OVER (ORDER BY old_id) 
    FROM Customers
)
UPDATE dbo.Customers
SET id = CTE.new_id
FROM CTE
WHERE CTE.old_id = dbo.Customers.old_id

-- Table "Orders" - rename column "id" to "old_id"
EXEC sp_rename 'dbo.orders.id', 'old_id'

-- add new "id" column
ALTER TABLE Orders ADD id INT 

-- update the FK references to the new "id" values in table "dbo.Customers"
UPDATE dbo.Orders 
SET fk = c.id
FROM dbo.Customers c
WHERE dbo.ORders.fk = c.old_id

-- fill new "id" column with sequential values, ordered by the "old_id" value
;WITH CTE AS
(
    SELECT old_id, new_id = ROW_NUMBER() OVER (ORDER BY old_id) 
    FROM dbo.Orders
)
UPDATE dbo.Orders
SET id = CTE.new_id
FROM CTE
WHERE CTE.old_id = dbo.Orders.old_id

-- drop the old, no longer required columns "old_id" from both tables
ALTER TABLE dbo.Customers DROP COLUMN old_id
ALTER TABLE dbo.Orders DROP COLUMN old_id

如果您没有引用这两个表之一的任何其他FK关系,那将会起作用。如果这样做,则可能需要在启动此升级脚本之前禁用或删除这些FK关系。

答案 1 :(得分:2)

如果这是你想做的一次性维护类型修复,我会这样做:

  1. 禁用所有外键
  2. 向您的customers表添加oldid
  3. 将当前ID字段放入oldid字段
  4. 用新ID
  5. 替换所有客户ID
  6. 使用来自客户表的oldid字段的加入/更新,使用现在已更新的ID更新订单表
  7. 删除oldid
  8. 添加您的foriegn键约束。

答案 2 :(得分:0)

  1. 删除外键。
  2. 使用额外列customers2和列OldId创建Id表作为IDENTITY。
  3. cutomers的所有行插入customers2(将customers.Id映射到customers2.OldId
  4. 请更新orders.fk设置orders.fk = customers2.id
  5. orders表格执行与{2}和第3点customers所做的相同的操作。
  6. 删除customers,删除orders,重命名customers2,重命名orders2
  7. 重新创建外键。