PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Postgres hàm INSERT hàng loạt bằng cách sử dụng các đối số JSON

Đối với hàng nghìn bản ghi

1. Tạo một bảng tạm thời gồm các hàng đầu vào, bao gồm các giá trị của bạn $1 , $2 , $3 . Cách tải lên nhanh nhất là COPY - hoặc \copy lệnh meta của psql nếu dữ liệu không nằm trên cùng một máy. Giả sử bảng này:

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

Tôi đã thêm một ràng buộc PK, điều này là hoàn toàn tùy chọn, nhưng nó đảm bảo rằng chúng tôi đang xử lý các giá trị int not-null duy nhất. Nếu bạn có thể đảm bảo cho dữ liệu đầu vào, bạn không cần phải ràng buộc.

2. Chuỗi các lệnh của bạn với các CTE sửa đổi dữ liệu. Như chúng tôi đã xác định trong câu hỏi trước của bạn , không có điều kiện chủng tộc nào để thực hiện trong hoạt động cụ thể này.

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;

Bước 1. và 2. phải chạy trong cùng một phiên (không nhất thiết phải là cùng một giao dịch), vì phạm vi của các bảng tạm thời được ràng buộc với cùng một phiên.

Lưu ý, UPDATE chỉ phụ thuộc vào INSERT đầu tiên , thành công của INSERT thứ 2 được đảm bảo, vì không có ON CONFLICT DO NOTHING và toàn bộ hoạt động sẽ được khôi phục nếu có bất kỳ xung đột nào trong INSERT thứ 2 .

Có liên quan:

Chỉ cho một vài bản ghi

Có nhiều lựa chọn như thế nào. Ý tưởng của bạn để truyền một mảng JSON cho một hàm là một trong số đó. Nếu các đối tượng khớp với bảng đích, bạn có thể sử dụng json_populate_recordset() trong một INSERT duy nhất truy vấn. Hoặc chỉ sử dụng INSERT (như câu lệnh đã chuẩn bị) mà không có trình bao bọc hàm.

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" }]');

Đối với chỉ một số ít cột, bạn cũng có thể chuyển một mảng cho mỗi cột và lặp qua chúng song song. Bạn có thể làm điều này với một vòng lặp đơn giản trên chỉ mục mảng. Vì Postgres 9.4 cũng có unnest() tiện lợi với nhiều tham số để thực hiện tất cả trong một truy vấn:

Giải pháp tốt nhất tùy thuộc vào định dạng dữ liệu mà bạn .




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL LIMIT với mệnh đề WHERE

  2. Tham gia tất cả các bảng PostgreSQL và tạo từ điển Python

  3. Tại sao tôi không thể truy vấn trực tiếp trên jsonb_array_elements?

  4. Hàm kích hoạt SQL để CẬP NHẬT đường trung bình hàng ngày khi CHÈN

  5. Loại ngày trong npgsql là gì?