web-dev-qa-db-ja.com

Postgresql、一意の値を持つ行が存在する場合は更新し、そうでない場合は挿入

URLテーブルがあります。それらは含む

(id int主キー、URL文字は一意に変化し、コンテンツ文字は変化し、最後に分析された日付)。

トリガーまたは何か(ルールがあります)を作成したいので、Javaプログラムから挿入するたびに、そのようなURLの行が存在する場合、単一行を更新します。インサート。

Postgresqlで完全なコードを提供してください。ありがとう。

31
Roman Lebedev

これは何度も聞かれています。可能な解決策はここにあります: https://stackoverflow.com/a/6527838/552671

このソリューションには、UPDATEINSERTの両方が必要です。

UPDATE table SET field='C', field2='Z' WHERE id=3;
INSERT INTO table (id, field, field2)
       SELECT 3, 'C', 'Z'
       WHERE NOT EXISTS (SELECT 1 FROM table WHERE id=3);

Postgres 9.1では、1つのクエリでそれを行うことができます: https://stackoverflow.com/a/1109198/2873507

57
Dave Halter

この投稿 このシナリオでより関連性が高いことがわかりました:

WITH upsert AS (
     UPDATE spider_count SET tally=tally+1 
     WHERE date='today' AND spider='Googlebot' 
     RETURNING *
)
INSERT INTO spider_count (spider, tally) 
SELECT 'Googlebot', 1 
WHERE NOT EXISTS (SELECT * FROM upsert)
6
dhruvpatel

INSERTSがまれな場合は、すべての更新でSELECTを発行するため、NOT EXISTS (...)の実行を避けます。代わりに、wildpeaksの回答をご覧ください: https://dba.stackexchange.com/questions/5815/how-can-i-insert-if-key-not-exist-with-postgresql

CREATE OR REPLACE FUNCTION upsert_tableName(arg1 type, arg2 type) RETURNS VOID AS $$ 
    DECLARE 
    BEGIN 
        UPDATE tableName SET col1 = value WHERE colX = arg1 and colY = arg2; 
        IF NOT FOUND THEN 
        INSERT INTO tableName values (value, arg1, arg2); 
        END IF; 
    END; 
    $$ LANGUAGE 'plpgsql'; 

この方法で、Postgresは最初にUPDATEを実行しようとします。影響を受けた行がない場合、INSERTを出力するようにフォールバックします。

4
chribsen