我有一个表在两列上有一个唯一的非聚集约束(我们称之为key
和value
)
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'))
答案 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