sql >> データベース >  >> RDS >> PostgreSQL

postgresSQLに挿入します

    そうしないでください! これまでそうすることさえ考えないでください!

    この間違った 解決策はあなたのために働くように見えるかもしれません(そうではありません):

    INSERT INTO lists VALUES ((SELECT max(id)+1 FROM lists),'KO','SPH', '5');
    

    しかし 、誰かがあなたと同時に挿入しようとすると、あなたは両方とも同じidを取得します 、これは無効な結果を引き起こします。本当にsequenceを使用する必要があります または、より信頼性の高いメカニズム(シーケンスに穴を開けることができない場合は補助テーブルが一般的ですが、いくつかの欠点があります[ロックされます])。 serialを使用することもできます 簡単にするためのデータ型(下にシーケンスを作成します):

    CREATE TABLE lists(id serial, col2 text, col3 text, ...);
    -- If you don't specify "id", it will autogenerate for you:
    INSERT INTO lists(col2, col3, ...) VALUES('KO','SPH', ...);
    -- You can also specify using DEFAULT (the same as above):
    INSERT INTO lists(id, col2, col3, ...) VALUES(DEFAULT, 'KO','SPH', ...);
    

    本当に、本当に、本当に、シーケンスを作成して使用できない場合は、上記のように実行できますが、例外を処理する必要があります(idを想定) フィールドはPKまたはUKであり、読み取りコミットトランザクションを使用します)、そのようなもの(PL / pgSQLの場合):

    DECLARE
        inserted bool = false;
    BEGIN
        WHILE NOT inserted LOOP;
            BEGIN
                INSERT INTO lists
                VALUES ((SELECT coalesce(max(id),0)+1 FROM lists),'KO','SPH', '5');
                inserted = true;
            EXCEPTION
                WHEN unique_violation THEN
                    NULL; -- do nothing, just try again
            END;
        END LOOP;
    END;
    

    しかし、繰り返しになりますが、それを避けることを強くお勧めします。シーケンスを使用して、幸せになりましょう... =D

    また、これが例であることはわかっていますが、INSERT INTOで明示的な列リストを使用してください 条項。




    1. RETURNINGはエラーを引き起こします:テーブルのFROM句エントリがありません

    2. このスタイルのユーザーメッセージングを実現するためのより簡単な方法はありますか?

    3. SQL NOT INが非常に遅いのはなぜですか?

    4. アグリゲートがUPDATEステートメントのセットリストに表示されない場合があります