我有一个用PostgreSQL编写的函数来遍历一个大表并将一堆值插入到另一个表中。输出很好,显然插入了大量的行,但实际上没有值插入到目标表中(我的代码中的“resources”表)。
我已尝试将insert语句放入事务中,但无济于事。是否存在某种我缺少的虚假访问或权限设置?我在网上找到了几个像我一样做这个的例子,所以我在这个上拉一点......
这是我的功能:
DECLARE
datatype_property record;
property record;
new_resource_id bigint;
BEGIN
RAISE NOTICE 'Starting...';
FOR datatype_property IN
SELECT * FROM datatype_properties
LOOP
RAISE NOTICE 'Trying to insert';
if not exists(select * from resources where uri = datatype_property.subject_resource) then
SELECT INTO new_resource_id NEXTVAL('resources_id_seq');
INSERT INTO resources (id, uri) VALUES(
new_resource_id,
datatype_property.subject_resource
);
RAISE NOTICE 'Inserted % with id %',datatype_property.subject_resource, new_resource_id;
end if;
END LOOP;
FOR property IN
SELECT * FROM properties
LOOP
if not exists(select * from resources where uri = property.source_uri) then
SELECT INTO new_resource_id NEXTVAL('resources_id_seq');
INSERT INTO resources (id, uri) VALUES(
new_resource_id,
resource.source_uri
) ;
RAISE NOTICE 'Inserted % with id %',resource.source_uri, new_resource_id;
end if;
if not exists(select * from resources where uri = property.destination_uri) then
SELECT INTO new_resource_id NEXTVAL('resources_id_seq');
INSERT INTO resources (id, uri) VALUES(
new_resource_id,
resource.source_uri
) ;
RAISE NOTICE 'Inserted % with id %',resource.source_uri, new_resource_id;
end if;
END LOOP;
RETURN;
END;
编辑:我已使用以下链接中的说明激活了plpgsql语言:
http://wiki.postgresql.org/wiki/CREATE_OR_REPLACE_LANGUAGE
编辑2:
此代码:
DECLARE
datatype_property record;
property record;
new_resource_id bigint;
BEGIN
insert into resources (id, uri) values ('3', 'www.google.com');
END
也不起作用:O
答案 0 :(得分:1)
你的问题听起来好像你没有投入你的交易(正如Pavel指出的那样),或者你用来检查行的工具是例如使用REPEATABLE READ作为其隔离级别或某种缓存。
但是你的功能不是一个很好的解决方案。在循环中逐个插入行总是一个坏主意。它比单个插入要慢得多(而且可扩展性较差)。
如果我没弄错的话,可以将这两个循环重写为以下语句:
insert into resource (id, uri)
select NEXTVAL('resources_id_seq'),
dt.subject_resource
from datatype_properties dt
where not exists (select 1
from resources r
where r.uri = dt.subject_resource);
insert into resources (id, uri)
select nextval('resources_id_seq'),
p.source_uri
from properties p
where not exists (select 1
from resources r
where r.uri = p.source_uri
or r.uri = p.destinatioin_uri);