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

Điều kiện chạy đua giữa SELECT và INSERT cho nhiều cột

Cờ lê trong hoạt động là SELECT f_insert_tag(tag_p_id, _tag) thay vì

SELECT * FROM f_insert_tag(tag_p_id, _tag)

Đối với Postgres 9.4

CREATE FUNCTION f_insert_tag(_tag_id int, _tag text, OUT _tag_id_ int, OUT _tag_ text) 
AS
$func$
 BEGIN
   INSERT INTO t(tag_id, tag)
   VALUES (_tag_id, _tag)
   RETURNING t.tag_id, t.tag
   INTO  _tag_id_, _tag_;

   EXCEPTION WHEN UNIQUE_VIOLATION THEN
      -- catch exception, return NULL
 END
$func$  LANGUAGE plpgsql;


CREATE FUNCTION f_tag_id(_tag_id int, _tag text, OUT _tag_id_ int, OUT _tag_ text) AS
$func$
BEGIN
LOOP
   SELECT t.tag_id, t.tag
   FROM   t
   WHERE  t.tag = _tag

   UNION ALL
   SELECT *                                              -- !!!
   FROM   f_insert_tag(_tag_id, _tag)
   LIMIT  1

   INTO _tag_id_, _tag_;

   EXIT WHEN _tag_id_ IS NOT NULL;  -- else keep looping
END LOOP;
END
$func$ LANGUAGE plpgsql;

db <> fiddle tại đây

Đối với Postgres 9.5 trở lên:

CREATE FUNCTION f_tag_id(_tag_id int, _tag text, OUT _tag_id_ int, OUT _tag_ text) AS
$func$
BEGIN
LOOP
   SELECT t.tag_id, t.tag
   FROM   t
   WHERE  t.tag = _tag
   INTO   _tag_id_, _tag_;

   EXIT WHEN FOUND;

   INSERT INTO t (tag_id, tag)
   VALUES (_tag_id, _tag)
   ON     CONFLICT (tag) DO NOTHING
   RETURNING t.tag_id, t.tag
   INTO   _tag_id_, _tag_;

   EXIT WHEN FOUND;
END LOOP;
END
$func$  LANGUAGE plpgsql;

db <> fiddle tại đây

Thông tin cơ bản tại đây:




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Xóa các bản ghi có số lặp lại nhiều hơn 5

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

  3. Cách clock_timestamp () hoạt động trong PostgreSQL

  4. Cách sqrt () hoạt động trong PostgreSQL

  5. Postgresql Drop View