2

PostgreSQLで記述された関数があり、大きなテーブルを調べて、別のテーブルに大量の値を挿入します。出力は問題なく、大量の行が挿入されているように見えますが、実際にはターゲットテーブル(私のコードでは「resources」テーブル)に値が挿入されていません。

トランザクション内に挿入ステートメントを入れてみましたが、役に立ちませんでした。私が見逃しているある種の厄介なアクセスまたは許可設定はありますか?私がやっているようにこれを行ういくつかの例をウェブ上で見つけたので、私はこれに少し髪を引っ張っています...

これが私の関数です:

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;  

終わり;

編集:次のリンクからの指示で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

4

1 に答える 1

1

問題は、トランザクションをコミットしていないように聞こえます(Pavelが指摘したように)、または行をチェックするために使用するツールは、たとえば、分離レベルまたはある種のキャッシュとしてREPEATABLEREADを使用しています。

しかし、あなたの関数はそもそも良い解決策ではありません。行を1つずつループに挿入することは、常に悪い考えです。単一の挿入を行うよりもはるかに遅くなります(そしてスケーラブルではなくなります)。

私が間違っていなければ、2つのループは次のステートメントに書き直すことができます。

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);
于 2012-07-20T16:19:33.613 に答える