0

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

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 列。

订单表中的链接行也必须重新编号,并且此表中的外键必须与客户表中的新编号匹配。

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

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 中执行此操作?

4

3 回答 3

6

绝对不需要在这里使用光标(哎呀!)......你需要这样的东西:

-- 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 关系。

于 2012-12-04T14:41:48.077 回答
2

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

  1. 禁用所有外键
  2. 在客户表中添加一oldid
  3. 将当前 ID 字段放入oldid字段中
  4. 将所有客户 ID 替换为新 ID
  5. oldid使用客户表中的字段上的连接/更新,使用现在更新的 id 更新订单表
  6. 删除oldid
  7. 添加你的外键约束。

于 2012-12-04T14:33:06.143 回答
0
  1. 删除外键。
  2. 创建customers2具有额外列OldId和列Id作为 IDENTITY 的表。
  3. 插入所有行 from cutomersto customers2(映射customers.Idcustomers2.OldId
  4. 更新orders.fk设置orders.fk=customers2.id
  5. orders表格执行与第customers2 点和第 3 点相同的操作。
  6. 删除customers,删除orders,重命名customers2,重命名orders2
  7. 重新创建外键。
于 2012-12-04T14:46:04.343 回答