Saya punya tabel some_table(id integer, x integer) Bagaimana cara menulis fungsi yang akan berfungsi dengan benar jika harus dijalankan secara bersamaan? Di sini versi saya saat ini:

CREATE OR REPLACE FUNCTION actualize_table(
  IN  p_id INTEGER,
  IN  p_x  INTEGER,
  OUT p_created BOOLEAN
)
LANGUAGE plpgsql
SECURITY DEFINER
AS $BODY$

BEGIN

  IF EXISTS(SELECT 1 FROM some_table WHERE id = p_id FOR SHARE) THEN
      p_created = FALSE;
  ELSE
      p_created = TRUE;
  END IF;

  INSERT INTO some_table (id) VALUES (p_id) ON CONFLICT (id) DO UPDATE SET x = p_x;

END;
$BODY$;

Tetapi tampaknya fungsi ini tidak akan berfungsi dengan benar jika baris tidak ada, sehingga tidak akan ada penguncian pada pemilihan. Maksud saya, akankah FOR SHARE berfungsi dengan benar dalam kasus itu? Bagaimana menurut anda?

0
Yakov Burtsev 20 November 2020, 21:04

1 menjawab

Jawaban Terbaik

Saya menemukan solusi dari dokumentasi postgresql: https://www.postgresql.org/docs /11/plpgsql-statements.html

Pernyataan UPDATE, INSERT, dan DELETE ditetapkan FOUND true jika setidaknya satu baris terpengaruh, false jika tidak ada baris yang terpengaruh.

 INSERT INTO some_table (id)
  VALUES (p_id)
  ON CONFLICT (id) DO NOTHING;
  IF FOUND THEN
      p_created = TRUE;
  ELSE
      p_created = FALSE;
  END IF;
0
Yakov Burtsev 19 Januari 2021, 19:18