2010-12-09 82 views
0

我有一個表有兩列「名稱」和「ID」。其中ID不爲空。Sql Server 2005交換ID號

我正在嘗試創建一個存儲過程,以便在兩個名稱之間交換ID時,此處的估算值就是我目前爲止的值。

CREATE PROCEDURE dbo.procName 
    @OldName NVARCHAR(128), 
    @NewName NVARCHAR(128) 
AS 

DECLARE @NewId0 INT, 
    @NewId1 INT, 
    @OldId0 INT, 
    @OldId1 INT, 
    @Number INT 


SELECT @NewId0 = ID FROM Table1 WHERE [Name] = @NewName 
SELECT @NewId1 = ID FROM Table1 WHERE [Name] = @NewName 
SELECT @OldId0 = ID FROM Table1 WHERE [Name] = @OldName 
SELECT @OldId1 = ID FROM Table1 WHERE [Name] = @OldName 
SELECT @Number = 0 

UPDATE Table1 SET ID = @Number WHERE ID = @NewId0 
UPDATE Table1 SET ID = @NewId1 WHERE ID = @OldId0 
UPDATE Table1 SET ID = @OldID1 WHERE ID = @NewID0 


Go 

我得到的是有值爲0

我覺得我的邏輯是正確的,但它似乎並不奏效的第一個名字在那裏,我失去了一些東西?

+0

如果你的表只有兩列,爲什麼不只是交換名稱列? – Arvo 2010-12-09 14:48:00

回答

3

嘗試像

UPDATE Table1 
SET  ID = CASE 
        WHEN ID = @NewId 
         THEN @OldId 
        ELSE @NewId 
       END 
WHERE ID IN (@NewId, @OldId) 

下面是一個完整的例子,如果ID是不是主鍵

CREATE PROCEDURE dbo.procName @oldname NVARCHAR

DECLARE @Table TABLE(
     ID INT, 
     Name VARCHAR(20) 
) 

INSERT INTO @Table SELECT 1,'A' 
INSERT INTO @Table SELECT 2,'B' 

DECLARE @NewName VARCHAR(20), 
     @OldName VARCHAR(20) 

SELECT @NewName = 'A', 
     @OldName = 'B' 

DECLARE @NewId INT, 
    @OldId INT 


SELECT @NewId = ID FROM @Table WHERE [Name] = @NewName 
SELECT @OldId = ID FROM @Table WHERE [Name] = @OldName 

SELECT * 
FROM @Table 

UPDATE @Table 
SET  ID = CASE 
        WHEN ID = @NewId 
         THEN @OldId 
        ELSE @NewId 
       END 
WHERE ID IN (@NewId, @OldId) 

SELECT * 
FROM @Table 
+0

這有效,但我忘了提及ID是主鍵。 – andy 2010-12-09 14:27:48

0

此腳本工作(128), @NewName NVARCHAR(128) As DECLARE @NewId INT, @OldId INT

SELECT @NewId = ID FROM表1 WHERE [名稱] = @newname
SELECT @OldId = ID FROM表1 WHERE [名稱] = @oldname

UPDATE表1 SET ID = CASE
WHEN ID = @NewId
THEN @OldId ELSE @NewId END WHERE ID IN(@NewId,@OldId)

SELECT * FROM TABL E1 去,因爲

0

您當前的代碼失敗:

  • 你看@ NewId0,並將其設置爲@number(即0)
  • 你再去找@ OldId0,並將其設置爲@ NewId1
  • 然後你看@再次NewId0 ......但兩行回來,你將其設置爲0,所以它不是在表中的任何更多

我喜歡@ astander的解決方案(upvoted),保存我把它寫出來小精靈。

但是......您的評論「... ID是主鍵」引發各種紅旗。你真的,真的不想改變主鍵值[插入從過去的類關於主鍵和關係完整性的長篇討論這裏]。弄清楚爲什麼你認爲你需要這樣做,然後找出另一種實現該業務需求的方式,例如:

  • 不要更改ID,更改其他所有內容(名稱,描述,成本,任何)
  • 創建全新的條目並丟棄(或標記爲已完成,被剔除或垃圾)舊的
  • 根據底層業務需求實施一些聰明的邏輯。
0

根據改變PK的擔憂,但它必須完成,因爲它會花費很長時間來改變所有其他的東西。這就是說我已經提出了一個答案。這僅僅是一個長腳本的第一部分,如此反覆的不完美:

CREATE PROCEDURE dbo.ID @OldName NVARCHAR(128), 
         @NewName NVARCHAR(128) 

AS 
DECLARE @NewId INT, 
     @OldId INT 

CREATE TABLE TmpTable (ID INT,Name NVARCHAR(128)) 

INSERT INTO TmpTable (Name,ID) 
VALUES (@NewName,(SELECT ID FROM Table1 WHERE [Name] = @NewName)); 

INSERT INTO TmpTable (Name,ID) 
VALUES(@OldName,(SELECT ID FROM Table1 WHERE [Name] = @OldName)) 

UPDATE Table1 SET ID = 11 WHERE [NAME] = @NewName 
UPDATE Table1 SET ID = 10 WHERE [NAME] = @OldName 

UPDATE Table1 SET ID = (SELECT ID FROM TmpTable where Name = @NewName)WHERE [Name] = @OldName 
UPDATE Table1 SET ID = (SELECT ID FROM TmpTable where Name = @OldName) WHERE [Name] = @NewName 

DROP TABLE TmpTable 
go 

「11」和「10」被選擇,因爲它們不是在表我的下一個任務將是查詢表1和一隨機數存在dosent,然後使用該數字臨時重新應用ID,然後更新新ID。

謝謝