当唯一性由两列的组合确定时,UPDATE或INSERT函数

时间:2012-11-28 21:07:12

标签: sql postgresql stored-procedures

扩展通常的INSERT OR UPDATE conondrum

我有一个提供正常UPDATE或INSERT的函数,它看起来像这样:

CREATE OR REPLACE FUNCTION updateslave ( varchar(7), smallint ) RETURNS void AS
$$
 BEGIN
   LOOP
     UPDATE consist SET
       master = $1,
       time = now() WHERE slave = $2;
     IF found THEN
       RETURN;
     END IF;
     BEGIN
       INSERT INTO consist(master, slave, time) VALUES ( $1, $2, now() );
       RETURN;
     EXCEPTION WHEN unique_violation THEN
       -- do nothing, then loop and retry
     END;
   END LOOP;
 END;
##
LANGUAGE plpgsql;

现在,问题在于我正在尝试将其重写为另一个表中的类似操作。但是,不同之处在于,在另一个表中没有单个唯一列,但两列的组合仅存在于一行中。是否可以根据两列的组合声明unique_violation?

为了保持示例的简单,我们假设该表看起来与我使用上述函数的表完全相同,但是master和slave是两个一起产生唯一性的列:

 Column |            Type             |                  Modifiers                   | Storage  | Description
--------+-----------------------------+----------------------------------------------+----------+-------------
 master | character varying(7)        | not null default 'unused'::character varying | extended |
 slave  | smallint                    | not null                                     | plain    |
 time   | timestamp without time zone | default now()                                | plain    |

1 个答案:

答案 0 :(得分:3)

最好的方法是在表上定义一个唯一约束,无论更新如何发生,即如果你的proc被使用,一切都没问题。

最简单的方法是在两列上创建唯一索引:

create unique index any_mame on mytable(col1, col2);

您也可以更改表格以添加唯一约束,但没有太大区别。