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

Không làm gì trong một thủ tục kích hoạt

Ví dụ của bạn bị hỏng. Nguồn và đích giống nhau trong INSERT của bạn trong trình kích hoạt, điều này bị ràng buộc đưa ra một vi phạm duy nhất mọi lần (ngoại trừ khi chèn NULL) - bị chặn bởi ON CONFLICT (test_name2) DO NOTHING , vì vậy không có gì xảy ra trong trình kích hoạt.

Bạn cũng quên về ràng buộc duy nhất trong INSERT ban đầu của bạn . Xem bên dưới.

INSERT INTO test2(test_name2)
   VALUES(NEW.test_name2)

...

CREATE TRIGGER trigger_test
AFTER INSERT
ON test2

Bắt đầu với một thiết lập ít khó hiểu hơn:

CREATE TABLE test1 (col1 text UNIQUE);
CREATE TABLE test2 (col2 text UNIQUE);

Và sẽ hiệu quả hơn nếu di chuyển pg_trigger_depth() cho chính trình kích hoạt. Vì vậy, điều này sẽ hoạt động, sao chép các hàng được chèn vào test1 tới test2 (và không phải theo cách khác), chỉ dành cho đầu tiên mức độ sâu kích hoạt:

CREATE OR REPLACE FUNCTION trig_test()
  RETURNS trigger AS
$func$
BEGIN
   INSERT INTO test2(col2)             -- !!
   VALUES (NEW.col1)                   -- !!
   ON     CONFLICT (col2) DO NOTHING;  -- !!

   RETURN NULL;
END
$func$ LANGUAGE plpgsql;

Tôi giữ nó là AFTER Kích hoạt. Có thể là BEFORE cũng kích hoạt, nhưng ở đó bạn cần RETURN NEW; .

CREATE TRIGGER trigger_test
AFTER INSERT ON test1                  -- !!
FOR EACH ROW 
WHEN (pg_trigger_depth() < 1)          -- !!
EXECUTE PROCEDURE trig_test();

Tại sao lại (pg_trigger_depth() < 1) ?

Lưu ý rằng bạn mắc phải các vi phạm duy nhất trong test2 theo cách này (không có gì xảy ra), nhưng vi phạm duy nhất trong test1 sẽ vẫn nêu ra một ngoại lệ trừ khi bạn có ON CONFLICT ... DO NOTHING ở đó nữa. Bài kiểm tra của bạn là mơ tưởng:

Phải là:

INSERT INTO test1 values ('test') ON CONFLICT (col1) DO NOTHING;

Thay thế:Chuỗi hai INSERT với một CTE

Nếu bạn có quyền kiểm soát INSERT lệnh trên test1 , bạn có thể làm điều này thay vì trình kích hoạt:

WITH ins1 AS (
   INSERT INTO test1(col1)
   VALUES ('foo')                  -- your value goes here
   ON CONFLICT (col1) DO NOTHING
   RETURNING *
   )
INSERT INTO test2(col2)
SELECT col1 FROM ins1
ON CONFLICT (col2) DO NOTHING;

Có liên quan:




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Làm thế nào để ánh xạ Postgres _INT8 với thực thể Java bằng Hibernate?

  2. Trong PostgreSQL, nhiều CẬP NHẬT cho các hàng khác nhau trong cùng một bảng có khóa xung đột không?

  3. Tìm các bài báo trong đó mảng

  4. Thêm Postgresql vào ứng dụng Heroku của tôi - vấn đề với các truy vấn lỗi cú pháp?

  5. Làm thế nào để có một khóa ngoại trỏ đến hai khóa chính?