PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Bagaimana saya bisa mendapatkan baris INSERTED dan UPDATED untuk operasi UPSERT di postgres

Jika Anda menambahkan kolom boolean yang diperbarui ke people tabel:

ALTER TABLE people ADD COLUMN updated bool DEFAULT FALSE;

maka Anda dapat mengidentifikasi baris yang diperbarui dengan menyetel updated = TRUE di DO UPDATE SET klausa:

INSERT INTO people (SELECT * FROM people_update)
  ON CONFLICT (name,surname)
    DO UPDATE SET age = EXCLUDED.age , street = EXCLUDED.street , city = EXCLUDED.city 
        , postal = EXCLUDED.postal
        , updated = TRUE
    WHERE 
      (people.age,people.street,people.city,people.postal) IS DISTINCT FROM 
      (EXCLUDED.age,EXCLUDED.street,EXCLUDED.city,EXCLUDED.postal)
RETURNING *;

Misalnya,

CREATE TABLE test.people (
    name text
    , surname text
    , age float
    , street text
    , city text
    , postal int
);
CREATE UNIQUE INDEX people_idx on people (name, surname);
ALTER TABLE people ADD COLUMN updated bool;
ALTER TABLE people ADD COLUMN prior_age float;
ALTER TABLE people ADD COLUMN prior_street text;
ALTER TABLE people ADD COLUMN prior_city text;
ALTER TABLE people ADD COLUMN prior_postal int;

INSERT INTO people (name, surname, age, street, city, postal) VALUES 
('Sancho', 'Panza', 414, '1 Manchego', 'Barcelona', 01605)
, ('Oliver', 'Twist', 182, '2 Stilton', 'London', 01837)
, ('Quasi', 'Modo', 188, $$3 Rue d'Arcole$$, 'Paris' , 01831 )
;

CREATE TABLE test.people_update (
    name text
    , surname text
    , age float
    , street text
    , city text
    , postal int
);

INSERT INTO people_update (name, surname, age, street, city, postal) VALUES 
('Sancho', 'Panza', 4140, '10 Idiazabal', 'Montserrat', 16050)
, ('Quasi', 'Modo', 1880, $$30 Champs Elysée$$ , 'Paris', 18310 )
, ('Pinocchio', 'Geppetto', 1380, '40 Nerbone', 'Florence', 18810)
;

INSERT INTO people (SELECT * FROM people_update)
  ON CONFLICT (name,surname)
    DO UPDATE SET 
        updated = TRUE
        , prior_age = (CASE WHEN people.age = EXCLUDED.age THEN NULL ELSE people.age END)
        , prior_street = (CASE WHEN people.street = EXCLUDED.street THEN NULL ELSE people.street END)
        , prior_city = (CASE WHEN people.city = EXCLUDED.city THEN NULL ELSE people.city END)
        , prior_postal = (CASE WHEN people.postal = EXCLUDED.postal THEN NULL ELSE people.postal END)
        , age = EXCLUDED.age 
        , street = EXCLUDED.street 
        , city = EXCLUDED.city 
        , postal = EXCLUDED.postal
    WHERE 
      (people.age,people.street,people.city,people.postal) IS DISTINCT FROM 
      (EXCLUDED.age,EXCLUDED.street,EXCLUDED.city,EXCLUDED.postal)
RETURNING *;

hasil

| name       | surname  |  age | street           | city       | postal | updated | prior_age | prior_street   | prior_city | prior_postal |
|------------+----------+------+------------------+------------+--------+---------+-----------+----------------+------------+--------------|
| Sancho     | Panza    | 4140 | 10 Idiazabal     | Montserrat |  16050 | t       |       414 | 1 Manchego     | Barcelona  |         1605 |
| Quasi      | Modo     | 1880 | 30 Champs Elysée | Paris      |  18310 | t       |       188 | 3 Rue d'Arcole |            |         1831 |
| Pinocchio  | Geppetto | 1380 | 40 Nerbone       | Florence   |  18810 | f       |           |                |            |              |

updated kolom menunjukkan ('Sancho', 'Panza') dan ('Quasi', 'Modo') baris telah diperbarui, dan('Pinocchio', 'Geppetto') adalah sisipan baru.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Daftar Partisi di Postgres 12

  2. Rails 3, Heroku:Ketuk Kesalahan Server:PGError:ERROR:urutan byte tidak valid untuk pengkodean UTF8:0xba

  3. Kunci asing PostgreSQL tidak ada, masalah warisan?

  4. Cara mempartisi tabel postgres menggunakan tabel perantara

  5. Memahami perbedaan antara parameter int literal vs int dalam fungsi PL/pgSQL