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

Nama kolom PL/pgSQL sama dengan variabel

Dengan asumsi id_pracownika adalah PRIMARY KEY dari meja. Atau setidaknya didefinisikan UNIQUE . (Jika bukan NOT NULL , NULL adalah kasus sudut.)

SELECT atau INSERT

Fungsi Anda adalah implementasi lain dari "SELECT or INSERT" - varian dari UPSERT masalah, yang lebih kompleks dalam menghadapi beban tulis bersamaan daripada yang terlihat. Lihat:

  • Apakah SELECT atau INSERT dalam fungsi rentan terhadap kondisi balapan?

Dengan UPSERT di Postgres 9.5 atau lebih baru

Di Postgres 9.5 atau yang lebih baru gunakan UPSERT (INSERT ... ON CONFLICT ... ) Detail di Wiki Postgres. Sintaks baru ini melakukan pekerjaan bersih :

CREATE OR REPLACE FUNCTION hire(
        _id_pracownika integer
      , _imie varchar
      , _nazwisko varchar
      , _miasto varchar
      , _pensja real)
  RETURNS text
  LANGUAGE plpgsql AS
$func$
BEGIN
   INSERT INTO pracownicy
          ( id_pracownika, imie, nazwisko, miasto, pensja)
   VALUES (_id_pracownika,_imie,_nazwisko,_miasto,_pensja);
   ON     CONFLICT DO NOTHING
   RETURNING 'OK';

   IF NOT FOUND THEN
      RETURN 'JUZ ISTNIEJE';
   END IF;
END
$func$;

Nama kolom yang memenuhi syarat tabel untuk disambiguasi jika perlu. (Anda juga dapat memberi awalan parameter fungsi dengan nama fungsi, tetapi itu menjadi canggung, dengan mudah.)
Tetapi nama kolom dalam daftar target INSERT mungkin tidak memenuhi syarat meja. (Lagi pula, tidak pernah ambigu.)

Sebaiknya hindari ambiguitas seperti itu secara apriori, itu kurang rawan kesalahan. Beberapa (termasuk saya) suka melakukannya dengan mengawali semua parameter fungsi dan variabel dengan garis bawah.

Jika Anda benar-benar membutuhkan nama kolom sebagai nama parameter fungsi juga, salah satu cara untuk menghindari tabrakan penamaan adalah dengan menggunakan ALIAS di dalam fungsi. Salah satu kasus langka dimana ALIAS sebenarnya berguna.

Atau parameter fungsi referensi menurut posisi ordinal:$1 untuk id_pracownika dalam hal ini.

Jika semuanya gagal, Anda dapat memutuskan apa yang didahulukan dengan menyetel #variable_conflict . Lihat:

  • Konflik penamaan antara parameter fungsi dan hasil JOIN dengan klausa USING

Masih ada lagi:

  • Ada seluk-beluk RETURNING klausa dalam UPSERT. Lihat:

    • Bagaimana cara menggunakan RETURNING dengan ON CONFLICT di PostgreSQL?
  • Literal string (konstanta teks) harus diapit oleh tanda kutip tunggal:'OK', bukan "OK" . Lihat:

    • Menyisipkan teks dengan tanda kutip tunggal di PostgreSQL
  • Menetapkan variabel relatif lebih mahal daripada dalam bahasa pemrograman lain. Pertahankan tugas seminimal mungkin untuk kinerja terbaik di plpgsql. Lakukan sebanyak mungkin dalam pernyataan SQL secara langsung.

  • VOLATILE COST 100 adalah dekorator default untuk fungsi. Tidak perlu mengejanya.

Tanpa UPSERT di Postgres 9.4 atau lebih lama

...
   IF EXISTS (SELECT FROM pracownicy p
             WHERE  p.id_pracownika = hire.id_pracownika) THEN
      RETURN 'JUZ ISTNIEJE';
   ELSE
      INSERT INTO pracownicy(id_pracownika,imie,nazwisko,miasto,pensja)
      VALUES (hire.id_pracownika,hire.imie,hire.nazwisko,hire.miasto,hire.pensja);
    
      RETURN 'OK';
   END IF;
...

Dalam EXISTS ekspresi, SELECT daftar tidak masalah. SELECT id_pracownika , SELECT 1 , atau bahkan SELECT 1/0 - semua sama. Cukup gunakan SELECT empty yang kosong daftar. Hanya keberadaan baris kualifikasi yang penting. Lihat:

  • Apa yang lebih mudah dibaca di subkueri EXISTS?


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Adaptor Postgresql (hal):tidak dapat terhubung ke server

  2. Cara Membuat Bilangan Ordinal di PostgreSQL

  3. Bagaimana cara menerapkan hubungan banyak ke banyak di PostgreSQL?

  4. Apakah ada cara untuk mengeksekusi kueri di dalam nilai string (seperti eval) di PostgreSQL?

  5. Buffer (Lingkaran) di PostGIS