我的部分功能如下所述。 当我执行该函数时,我收到一条错误,指出alarm_id
的主键违规SELECT COUNT(DISTINCT exception_sub_type) INTO v_count FROM mdas.alarm_configuration;
IF v_count > 0 THEN
FOR i IN 1..v_count
LOOP
SELECT ((MAX(alarm_id))+1) INTO v_alarm_id FROM mdas.alarm_configuration;
RAISE NOTICE 'ALARM ID (%)',v_alarm_id;
INSERT INTO mdas.alarm_configuration
(alarm_id,
exception_sub_type,
exception_type,
from_range,
groups,
priority,
sub_group,
to_range,
org_unit_id,
status)
SELECT DISTINCT ON(exception_sub_type) v_alarm_id,
exception_sub_type,
exception_type,
from_range,
v_group_name,
priority,
v_subgroup_name,
to_range,
v_org_unit_id,
status
FROM mdas.alarm_configuration
WHERE groups = v_group_name AND mdas.alarm_configuration.org_unit_id = v_org_unit_id;
END LOOP;
END IF;
注意:这只是该功能的一部分。该函数有三个参数v_org_unit_id,v_group_name和v_subgroup_name。我的主键是alarm_id,我想增加1并根据表中提供的MAX插入。
答案 0 :(得分:1)
在您的环境中,当两个以上的客户端同时调用该函数时,它们将看到相同的alarm_id,因此引发了唯一的违反。 对于exp:
SESSION A :
select max(id) into v_id from test;
insert into test values (v_id);
.. not end else.
SESSION B :
select max(id) into v_id from test; -- this v_id will same as session a.
insert into test values (v_id);
and then session A commit;
SESSION B will raise error.
ERROR: duplicate key value violates unique constraint "test_pkey"
DETAIL: Key (id)=(?) already exists.
你可以使用PostgreSQL串口处理这个问题。 喜欢:
digoal=# create table test (id serial primary key, other_cols type ...);
CREATE TABLE
并且不需要使用max(id),您只需要键入其他列的值。 像
insert into test (other_cols,...) values (...);