Sql Server 2005交换ID号

时间:2010-12-09 12:34:46

标签: sql-server-2005

我有一个包含两列“name”和“ID”的表。其中ID不为空。

我正在尝试创建一个存储的prcedure来交换两个名称的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的名称。

我认为我的逻辑是正确的,但它似乎没有用,是否有我遗漏的东西?

4 个答案:

答案 0 :(得分:3)

尝试类似

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

这是一个完整的例子

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

答案 1 :(得分:0)

如果ID不是主键

,则此脚本有效

CREATE PROCEDURE dbo.procName                               @OldName NVARCHAR(128),                               @NewName NVARCHAR(128) 如 DECLARE @NewId INT,         @OldId INT

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

更新表1 SET ID = CASE
                当ID = @NewId时                 然后@OldId                 ELSE @NewId                 结束 ID IN(@NewId,@ OldId)

SELECT * 从表1 去

答案 2 :(得分:0)

您当前的代码失败,原因是:

  • 您查找@ NewId0,并将其设置为@Number(为0)
  • 然后查找@ OldId0,并将其设置为@ NewId1
  • 然后你再次寻找@ NewId0 ......但是两行回来了,你把它设置为0,所以它不再在表中了

我喜欢@ astander的解决方案(upvoted),救了我自己写出来。

但是......你的评论,“...... ID是主键”,会引发各种危险信号。你真的,真的不想改变主键值[从过去的类中插入关于主键和关系完整性的长篇讨论]。弄清楚为什么你认为你需要这样做,然后找出实现该业务需求的另一种方法,例如:

  • 不要更改ID,更改其他所有内容(名称,描述,费用等)
  • 创建全新的条目并删除(或标记为已完成,已删除或垃圾)旧的条目
  • 根据基本业务需求实现一些聪明的逻辑。

答案 3 :(得分: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”被选中,因为它们不在表格中,我的下一个任务是查询table1,并且对于存在剂量的随机数,然后使用该数字来重新计算ID,然后再更新新的ID。

由于