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

JSON引数を使用したPostgresバルクINSERT関数

    何千ものレコードの場合

    1。$1で構成される入力行の一時テーブルを作成します 、$2$3 。アップロードする最速の方法は、 COPYです。 -または \copy psqlのメタコマンド データが同じマシン上にない場合。このテーブルを想定してみましょう:

    CREATE TEMP TABLE tmp(id int PRIMARY KEY, val1 text, val2 text);
    

    完全にオプションのPK制約を追加しましたが、一意のnull以外のint値を処理していることを確認します。入力データを保証できる場合は、制約は必要ありません。

    2。 コマンドをデータ変更CTEと連鎖させます。 前の質問 で判断したとおり 、この特定の操作で処理する競合状態はありません。

    WITH ins1 AS (
       INSERT INTO table1 AS t1 (id, val1, val2)
       SELECT id, val1, val2 FROM tmp ON CONFLICT DO NOTHING
       RETURNING t1.id, t1.val1, t1.val2  -- only actually inserted rows returned
       )
    , ins2 AS (
       INSERT INTO table2 (table1_id, val1)
       SELECT id, val1 FROM ins1
       )
    UPDATE table3 t3
    SET    val2 = i.val2
         , time = now()
    FROM   ins1 i
    WHERE  t3.table1_id = i.id;
    

    手順1と2は、同じセッションで実行する必要があります (必ずしも同じトランザクションである必要はありません)。一時テーブルのスコープは同じセッションにバインドされているためです。

    UPDATEに注意してください 最初のINSERTにのみ依存します 、2番目のINSERTの成功 ON CONFLICT DO NOTHINGがないため、保証されます。 2番目のINSERTで競合が発生した場合、操作全体がロールバックされます。 。

    関連:

    ほんの数レコード

    どのようにさまざまなオプションがあります。 JSON配列を関数に渡すというアイデアはその1つです。オブジェクトがターゲットテーブルと一致する場合は、 json_populate_recordset() 単一のINSERT クエリ。または、INSERTを使用します (プリペアドステートメントとして)関数ラッパーなし。

    INSERT INTO target_tbl  -- it's ok to omit target columns here
    SELECT *
    FROM   json_populate_recordset(null::target_tbl,  -- use same table type
              json '[{ "id": "1", "val1": "1-val1", "val2": "1-val2" },
                     { "id": "2", "val1": "2-val1", "val2": "2-val2" },
                     { "id": "3", "val1": "3-val1", "val2": "3-val2" },
                     { "id": "4", "val1": "4-val1", "val2": "4-val2" }]');
    

    ほんの一握りの列の場合、各列に配列を渡し、それらを並列にループすることもできます。これは、配列インデックスの単純なループで実行できます。 Postgres 9.4以降、便利なunnest()もあります。 1つのクエリですべてを実行するための複数のパラメータを使用:

    最適なソリューションは、使用しているデータ形式によって異なります




    1. Grails:列挙型のmysqlフィールドをドメインクラスにマップします

    2. ログインスクリプトが必要に応じて機能しない

    3. 複数列のSQLMAX?

    4. MySQLの全文検索の前に*(アスタリスク)を付ける