2012-12-04 96 views
0

重新編號INT列順序我有以下兩個表和數據: -SQL Server中,兩個表

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') 
; 

我想要做的是重新編排兩個表中的id列從1開始順序。

訂單表中的鏈接行也必須重新編號,並且此表中的外鍵必須與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這樣做呢?

+7

你有這樣做的好理由嗎? – Joe

+0

一次性數據清理修復,我真的想避免這樣做,但由於我無法控制的原因,它是唯一的簡單解決方案。對您的評論+1。 –

回答

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關係。

+0

非常好。這有助於我對問題進行大規模分類。非常感謝。 –

+0

爲什麼不設置更新以在參考約束中級聯?臨時列將不是必需的 – WKordos

+1

@WKordos:你可以這樣做 - 但是你必須刪除現有的FK約束,用'ON CASCADE UPDATE'創建一個新的約束,並且很可能再次丟棄舊約最後 - 看起來你並沒有真正獲得太多的東西....另外:我更喜歡在我完全控制下手動完成這樣的事情 - 我不喜歡依賴那些「半巫術「技巧:-) –

2

如果這是你想要做一次維護支持類修復,我想先做到這一點:

  1. 禁用所有foregin鍵
  2. 一個oldid列添加到您的客戶表
  3. 放當前的ID字段進入oldid字段
  4. 用新ID替換所有客戶ID
  5. 使用上的加入/更新來更新訂單表與現在使用的ID 0字段從客戶表中刪除
  6. 刪除oldid
  7. 加回您的foriegn鍵約束。

0
  1. 刪除外鍵。
  2. 創建customers2表的額外列OldId和列Id作爲IDENTITY。
  3. 插入所有從cutomerscustomers2(與映射customers.Idcustomers2.OldId
  4. 不需更新上orders.fk行設置orders.fk = customers2.id
  5. 請與orders表,你在點2和3的所作所爲與customers相同。
  6. 下降customers,下降orders,重命名customers2,重命名orders2
  7. 重新創建外鍵。