唯一键值对的SQL更新

时间:2018-05-17 08:41:28

标签: sql sql-server

我有一个表在两列上有一个唯一的非聚集约束(我们称之为keyvalue

CREATE TABLE table (
  id varchar(50), key varchar(64) NOT NULL, value varchar(64) NOT NULL, ...
  CONSTRAINT pk_table_id PRIMARY KEY CLUSTERED (id ASC) WITH (...) ON [PRIMARY],
  CONSTRAINT pk_key_value UNIQUE NONCLUSTERED ( key ASC, value ASC) WITH (...) ON PRIMARY
) ON [PRIMARY]

现在我需要编写一个安全更新脚本来更新所有具有key='oldKey'的行,其中安全更新脚本意味着它必须能够多次执行,而不会抛出异常。

我在开始时所拥有的是:

UPDATE table
SET key = 'newKey'
WHERE key = 'oldKey'

在第一次执行时工作(由于约束)。

假设我的key='oldKey'value='b'行已更新为key='newKey'value='b'。现在插入了两个新行,一个包含key='oldKey'value='b',另一个包含key='oldKey'value='c',并且再次运行更新脚本。由于密钥已更新为'newKey'且键值对newKey, b已存在,因此会引发异常。

我现在要做的是创建一个更新语句,更新所有key='oldKey'并且没有键值对key='newKey' value='b'已存在的行,否则不执行任何操作。

这是我到目前为止所尝试的:

-- 1st try, nothing is updated
IF NOT EXISTS (SELECT * FROM table WHERE key='newKey' AND value IN (SELECT value FROM table WHERE key='oldKey'))
BEGIN
  UPDATE table
  SET key = 'newKey'
  WHERE key = 'oldKey'
END

-- 2nd try, exception thrown
UPDATE table
SET key = 'newKey'
WHERE key = 'oldKey' AND
  (SELECT COUTN(*) FROM table WHERE key='newKey' AND value IN (SELECT value FROM table WHERE key='oldKey')) > 0

-- 3rd try, nothing is updated
UPDATE table
SET key = 'newKey'
WHERE NOT EXISTS (SELECT * FROM table WHERE key='newKey' AND value IN (SELECT value FROM table WHERE key='oldKey'))

2 个答案:

答案 0 :(得分:2)

试试这个:

UPDATE t1
SET key = 'newKey'
from table t1
WHERE key = 'oldKey'
and NOT EXISTS (SELECT * FROM table t2 WHERE t2.key='newKey' AND t1.value=t2.value)

答案 1 :(得分:2)

尝试

UPDATE t SET key = 'newKey' 
FROM yourtable t
LEFT JOIN yourtable t1 ON t1.value = t.value
    AND t1.key = 'newKey'
WHERE t.key = 'oldKey'
    AND t1.value IS NULL