更新:在对我的代码进行大量检测之后,我找到了另一个开发人员在不使用“upsert”功能的情况下插入此表的地方。但是,由于方法的分组方式和异常捕获的方式,堆栈跟踪表明该函数出错,而事实上,没有调用该函数就是错误。下面的代码很好(丹尼尔添加了警告)。
我有以下 plpgsql 函数:
-- http://www.depesz.com/2012/06/10/why-is-upsert-so-complicated/
CREATE OR REPLACE FUNCTION upsert_person_site(
curr_site_id INTEGER,
curr_person_id INTEGER,
curr_job_title CHARACTER VARYING(128)
) RETURNS void as $$
BEGIN
-- strictly speaking, running the update first is not needed and
-- duplicate code, but exceptions are relatively expensive.
-- Also, note that we refuse to update with a NULL job title because an
-- import may simply fail to specify one.
UPDATE person_site
SET job_title = curr_job_title
WHERE site_id = curr_site_id
AND person_id = curr_person_id
AND curr_job_title IS NOT NULL;
IF FOUND THEN
RETURN;
END IF;
BEGIN
INSERT INTO person_site ( site_id, person_id, job_title )
VALUES ( curr_site_id, curr_person_id, curr_job_title );
EXCEPTION WHEN OTHERS THEN
UPDATE person_site
SET job_title = curr_job_title
WHERE site_id = curr_site_id
AND person_id = curr_person_id
AND curr_job_title IS NOT NULL;
END;
RETURN;
END;
$$ language plpgsql;
目的是在记录存在时进行更新,如果不存在则插入。预期的逻辑是:
// duplicating the update to avoid trapping an expensive exception
try to update the record
if successful
return
try
// I believe it's failing here
insert a new record
catch
update an existing record
该person_site
表有一个person_site_pkey
和person_id
字段site_id
。但是,很多次运行此函数时,我都会收到异常声明duplicate key value violates unique constraint "person_site_pkey" at ...
。
有人可以帮助我了解我所缺少的吗?我以为EXCEPTION WHEN OTHERS
方块会困住它。
这是在 Debian Squeezebox 上运行的 Postgresql 8.4.13。应用程序代码是 Perl 并使用DBD::Pg模块。