web-dev-qa-db-ja.com

単純なpg / plsqlループの例

Postgresでテーブルスキーマを再設計しています。以前は、パートナーと広告主の間に多くの関係があると想定していたため、名前partner_advertiserの2つのテーブルpartneradvertiserへのリンカーテーブルがありました。 advertiserpartnerを1つだけ持つように変更が加えられたため、partneradvertiserと1つの関係になります。

以前の情報を失うことなく変更を加えるにはどうすればよいですか?新しいスキーマ設計のマッピングを入力するには、リンカーテーブルデータを使用する必要があります。これが私の最初のコードです:

BEGIN

FOR r IN SELECT partnerid, advertiserid from partner_advertiser
    LOOP
    NEXT r;
    UPDATE advertiser SET partnerid = r.partnerid WHERE id = r.advertiserid 
    END LOOP;

END

ところで、私はpg/plsqlを自分で実行していません。ですから、私がすべき基本的なステップがあれば、私に注意を促してください。

7
ivanceras

次を使用できます。

UPDATE advertiser a SET partnerid = r.partnerid
FROM partner_advertiser r
WHERE a.id = r.advertiserid

一般に、これらのような単純なリレーショナル変換にはループは必要ありません。ただし、本当に必要な場合は、 http://www.postgresql.org/docs/9.0/interactive/plpgsql-control-structures.html を参照してください。

特記事項:広告主IDがまだ一意でない場合、変換によってデータが明らかに失われるため、最初に次のようなものを実行する必要があります。

SELECT count(*), advertiserid FROM partner_advertiser
GROUP BY advertiserid HAVING COUNT(*) > 1

それによって行が返される場合は、手動で修正する必要があります。

12
qmajor

これも機能します。単純なplpgsqlスニペットの使用:

CREATE OR REPLACE FUNCTIOn migratePartnerAdvertiser() RETURNS int4 AS '
DECLARE r RECORD;

BEGIN
    FOR r IN SELECT * from partner_advertiser LOOP
            UPDATE advertiser SET partnerId = r.partnerId WHERE id = r.advertiserId; 
    END LOOP;
return 1;
END;
' LANGUAGE plpgsql;


SELECT migratePartnerAdvertiser() as output;
6
ivanceras