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

PostgreSQL memodifikasi bidang secara dinamis dalam catatan BARU dalam fungsi pemicu

Tidak ada solusi sederhana berbasis plpgsql. Beberapa solusi yang mungkin:

  1. Menggunakan hstore ekstensi.
CREATE TYPE footype AS (a int, b int, c int);

postgres=# select row(10,20,30);
    row     
------------
 (10,20,30)
(1 row)

postgres=# select row(10,20,30)::footype #= 'b=>100';
  ?column?   
-------------
 (10,100,30)
(1 row)

hstore fungsi berbasis bisa sangat sederhana:

create or replace function update_fields(r anyelement,
                                         variadic changes text[])
returns anyelement as $$
select $1 #= hstore($2);
$$ language sql;

postgres=# select * 
             from update_fields(row(10,20,30)::footype, 
                                'b', '1000', 'c', '800');
 a  |  b   |  c  
----+------+-----
 10 | 1000 | 800
(1 row)
  1. Beberapa tahun yang lalu saya menulis ekstensi pl kotak alat . Ada fungsi record_set_fields :
pavel=# select * from pst.record_expand(pst.record_set_fields(row(10,20),'f1',33));
 name | value |   typ   
------+-------+---------
 f1   | 33    | integer
 f2   | 20    | integer
(2 rows)

Mungkin Anda dapat menemukan beberapa solusi hanya plpgsql berdasarkan beberapa trik dengan tabel dan array sistem seperti ini , tapi saya tidak bisa menyarankannya. Itu terlalu kurang dapat dibaca dan untuk pengguna yang tidak mahir hanya ilmu hitam saja. hstore sederhana dan hampir di mana-mana sehingga harus menjadi cara yang disukai.

Di PostgreSQL 9.4 (mungkin 9.3) Anda dapat mencoba sihir hitam dengan manipulasi JSON:

postgres=# select json_populate_record(NULL::footype, jo) 
              from (select json_object(array_agg(key),
                                       array_agg(case key when 'b' 
                                                          then 1000::text
                                                          else value 
                                                 end)) jo
       from json_each_text(row_to_json(row(10,20,30)::footype))) x;
 json_populate_record 
----------------------
 (10,1000,30)
(1 row)

Jadi saya bisa menulis fungsi:

CREATE OR REPLACE FUNCTION public.update_field(r anyelement, 
                                               fn text, val text, 
                                               OUT result anyelement)
 RETURNS anyelement
 LANGUAGE plpgsql
AS $function$
declare jo json;
begin
  jo := (select json_object(array_agg(key), 
                            array_agg(case key when 'b' then val
                                               else value end)) 
            from json_each_text(row_to_json(r)));
  result := json_populate_record(r, jo);
end;
$function$

postgres=# select * from update_field(row(10,20,30)::footype, 'b', '1000');
 a  |  b   | c  
----+------+----
 10 | 1000 | 30
(1 row)

Fungsi berbasis JSON seharusnya tidak terlalu cepat. hstore harus lebih cepat.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Dapatkan semua prosedural, fungsi yang ditentukan pengguna

  2. masukkan nilai DEFAULT

  3. Referensi parameter psql di dalam blok anonim PL/pgSQL

  4. django.db.utils.ProgrammingError:relasi bot_trade tidak ada

  5. Apakah ada masalah kinerja menyimpan file di PostgreSQL?