我有一对表,其中第一个表存储不可变的“父”对象,第二个表存储这些对象的可变方面,保留所有这些值的完整历史记录。为了在设置给定父级的值时(特别是在父级可能不存在时)使事情更快一些,我试图获取一个存储过程,该存储过程将找到父级,如果不存在则创建父级,然后创建附加到该父项的可变片段,然后返回该可变片段。不幸的是,当我尝试将其与父级重新连接时,如果父级不存在,则结果为空。
示例设置:
create table myvars (
id serial unique,
name text
);
create table myvalues (
id serial unique,
varid int references myvars(id),
value text
);
insert into myvars (name) values('var1'), ('var2');
insert into myvalues (varid, value) values (1, 'val11'), (1, 'val12');
以及为此存储的过程:
create or replace function find_or_create_value(_var text, _value text)
returns setof myvalues
as $$
declare
v myvars;
begin
select * into v
from myvars var where _var = var.name;
if not found then
insert into myvars (name) values(_var)
returning * into v;
end if;
return query insert into myvalues (varid, value) values(v.id, _value) returning *;
end
$$
language plpgsql volatile;
最后,失败的查询:
select *
from find_or_create_value('foo2', 'bar2') fcv
join myvars mv
on fcv.varid = mv.id;
我现在想出了一种解决方法,该方法是在存储过程中进行联接,并返回包含两个记录的表,然后调用者不需要进行联接。但是,这对我来说似乎有点违反直觉,并且由于我并不总是需要这些额外的信息,因此它也不太干净,所以我宁愿调用方通过在连接时选择是否包含myvars数据来进行选择。必要,而不是不必要时。我希望找到一种方法,使它只返回一个myvalue记录而不返回myvars记录。
编辑:
我还应该指出,存储过程“成功”之处在于插入成功。并从中查询有效。但是,当我将它加入刚刚创建辅助值的表时,即使存储过程保证存在匹配项,也不能令人满意,因为在ON条件下显然无法满足要求。