код вставки
INSERT INTO employee (pid, pname, desig, dept, lts_i, lts_O, p_status) VALUES %s \
ON CONFLICT (pid) DO UPDATE SET \
(pname, desig, dept, lts_i, lts_O, p_status) = \
(EXCLUDED.pname, EXCLUDED.desig, EXCLUDED.dept, EXCLUDED.lts_i, EXCLUDED.lts_O, EXCLUDED.p_status) \
RETURNING *
Если я вставлю такой как выше, то он работает хорошо. Вместо КОНФЛИКТА я использовал функцию, следующую
CREATE FUNCTION employee_db(
pid1 integer,
pname1 text,
desig1 text,
dept1 text,
lts_i1 time,
lts_o1 time,
p_status1 text
) RETURNS VOID AS
$$
BEGIN
LOOP
-- first try to update the key
-- note that "a" must be unique
UPDATE employee SET (lts_i, lts_o, p_status) = (lts_i1, lts_o1, p_status1) WHERE pid = pid1;
IF found THEN
RETURN;
END IF;
-- not there, so try to insert the key
-- if someone else inserts the same key concurrently,
-- we could get a unique-key failure
BEGIN
INSERT INTO employee(pid, pname, desig, dept, lts_i, lts_o, p_status) VALUES (pid1, pname1, desig1, dept1, lts_i1, lts_o1, p_status1);
RETURN;
EXCEPTION WHEN unique_violation THEN
-- do nothing, and loop to try the UPDATE again
END;
END LOOP;
END;
$$
LANGUAGE plpgsql;
это требует некоторого аргумента
SELECT merge_db(12, 'Newton', 'director', 'd1', '10:00:26', '00:00:00', 'P-Status')"
но когда я обновляю lts_i, lts_O и p_status в пределах одного и того же идентификатора (12)
SELECT merge_db(12, 'Newton', 'director', 'd1', '12:10:22', '02:30:02', 'active')"
тогда также отображается ошибка дубликата ключа.
Я не хочу использовать здесь CONFLICT, потому что у меня есть правило UPDATE для той же таблицы, и уже postgresql говорит, что «Событие является одним из SELECT, INSERT, UPDATE или DELETE. Обратите внимание, что INSERT, содержащий предложение ON CONFLICT не может использоваться в таблицах с правилами INSERT или UPDATE. Попробуйте вместо этого использовать обновляемое представление. "
Обновление правила
CREATE RULE log_employee AS ON UPDATE TO employee
WHERE NEW.lts_i <> OLD.lts_i or NEW.lts_O <> OLD.lts_O
DO UPDATE employee set today = current_date where id = new.id;
если обновляется lts_i, lts_o или p_status, то будет вставлено current_date в поле "today" в той же таблице сотрудников.
Но определенно мне нужно ПРАВИЛО. В этой ситуации что мне делать?
Любая помощь будет принята с благодарностью.
Спасибо.