编写单个UPDATE语句以防止重复

时间:2012-08-16 14:17:01

标签: sql sql-server oracle11g

我已经尝试了几个小时(可能比我需要的更多)找出编写更新sql查询的最佳方法,该查询将不允许我正在更新的列上的重复项。

意思是,如果TableA.ColA已经有一个名字'TEST1',那么当我改变另一条记录时,我就不能为ColA选择一个值为'TEST1'。

简单地将查询分成select,并使用允许条件逻辑的服务器层代码非常简单:

SELECT ID, NAME FROM TABLEA WHERE NAME = 'TEST1'

IF TableA.recordcount > 0 then
    UPDATE SET NAME = 'TEST1' WHERE ID = 1234
END IF

但是我更感兴趣的是看看这两个查询是否可以组合成一个查询。

我正在使用Oracle来解决问题,但我也希望看到一个SQL Server查询。我认为MERGE语句可以起作用,但由于显而易见的原因,你不能使用该条款:

..etc.. WHEN NOT MATCHED UPDATE SET ..etc.. WHERE ID = 1234

如果在连接中提到了列,则无法更新列(oracle限制但不限于SQL Server)

另外,我知道你可以在一个阻止重复值的列上设置约束,但是我有兴趣看看是否有这样的查询可以在不使用约束的情况下执行此操作。

这是一个示例启动尝试,只是为了看看我能想出什么(解释失败是没有必要的):

错误:ORA-01732:此视图上的数据操作操作不合法

UPDATE (
    SELECT d.NAME, ch.NAME FROM (
        SELECT 'test1' AS NAME, '2722' AS ID
        FROM DUAL
    ) d
    LEFT JOIN TABLEA a
    ON UPPER(a.name) = UPPER(d.name)
)
SET a.name = 'test2'
WHERE a.name is null and a.id = d.id

我尝试过合并,但只是放弃了认为这是不可能的。我也认为不存在(但我必须要小心,因为我可能会不小心更新所有其他不符合标准的记录)

2 个答案:

答案 0 :(得分:2)

应该是直截了当的:

update personnel
set personnel_number = 'xyz'
where person_id = 1001
and not exists (select * from personnel where personnel_number = 'xyz');

答案 1 :(得分:1)

如果我理解正确,您希望有条件地更新字段,假设找不到该值。以下查询执行此操作。它应该在SQL Server和Oracle中都有效:

update table1
    set name = 'Test1'
    where (select count(*) from table1 where name = 'Test1') > 0 and
          id = 1234