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

Làm cách nào để PostgreSQL chèn một hàng vào bảng khi bị xóa khỏi bảng khác?

Viết một hàm kích hoạt. Một cái gì đó như thế này:

CREATE OR REPLACE FUNCTION trg_backup_row()
  RETURNS trigger AS
$BODY$
BEGIN

INSERT INTO other_tbl
SELECT (OLD).*, t.other_col                -- all columns of from old table
-- SELECT OLD.col1, OLD.col2, t.other_col  -- alternative: some cols from old tbl
FROM   third_tbl t
WHERE  t.col = OLD.col  -- link to third table with info from deleted row
AND    <unique_condition_to_avoid_multiple_rows_if_needed>;

RETURN NULL;

END;
$BODY$
  LANGUAGE plpgsql VOLATILE;

Và một trình kích hoạt ON DELETE . Như thế này:

CREATE TRIGGER delaft
  AFTER DELETE
  ON tbl
  FOR EACH ROW
  EXECUTE PROCEDURE trg_backup_row();

Các yếu tố chính

  • Tốt nhất hãy biến nó thành trình kích hoạt SAU KHI XÓA CHO TỪNG ROW .

  • Để trả về tất cả các cột từ bảng cũ, hãy sử dụng cú pháp (OLD). * . Xem hướng dẫn về cách truy cập các loại kết hợp . Hoặc OLD. * cũng là cú pháp hợp lệ vì OLD được thêm vào FROM mệnh đề ngầm định. Để có VALUES biểu thức nó sẽ phải là (OLD). * , Tuy nhiên. Như:

    INSERT INTO other_tbl
    VALUES((OLD).*, some_variable)
    
  • Bạn có thể bao gồm các giá trị từ bất kỳ bảng nào khác như tôi chứng minh. Chỉ cần đảm bảo có một hàng duy nhất hoặc bạn tạo nhiều mục nhập.

  • Khi trình kích hoạt kích hoạt SAU sự kiện, hàm có thể RETURN NULL .

Giới thiệu về khả năng hiển thị

Đáp lại bình luận thận trọng của @ couling.

Mặc dù khóa ngoại có thể được khai báo là DEFERRED , điều này sẽ chỉ trì hoãn việc kiểm tra tính toàn vẹn chứ không phải chính việc xóa. Các hàng bị xóa trong trình kích hoạt được thực thi trước khi hàng được thực hiện trước hoặc bởi ON DELETE CASCADE khóa ngoại sẽ không hiển thị nữa tại thời điểm này SAU KHI XÓA trình kích hoạt được gọi. (Tất cả đều xảy ra trong một giao dịch rõ ràng. Không có chi tiết nào trong số này quan trọng đối với các giao dịch khác, sẽ thấy tất cả hoặc không có ảnh hưởng nào. Tham khảo hướng dẫn sử dụng để biết thêm về Mô hìnhMVCC và cách ly giao dịch .)

Do đó, nếu bạn muốn bao gồm các giá trị từ các hàng theo cách như vậy trong INSERT của bạn , hãy nhớ gọi trình kích hoạt này trước những hàng đó sẽ bị xóa.

Bạn có thể phải thực hiện kích hoạt này TRƯỚC KHI XÓA .

Hoặc có thể có nghĩa là bạn phải sắp xếp các trình kích hoạt của mình cho phù hợp, TRƯỚC kích hoạt đến trước SAU rõ ràng là kích hoạt. Và các trình kích hoạt ở cùng cấp được thực thi theo thứ tự bảng chữ cái .

Tuy nhiên, miễn là tôi siêu chính xác ở đây, tôi cũng có thể thêm những thay đổi được thực hiện đối với hàng (hoặc hàng tùy thuộc) trong BEFORE khác trình kích hoạt cũng chỉ hiển thị nếu chúng được gọi là trước cái này.

Lời khuyên của tôi để biến nó thành SAU trình kích hoạt là vì nó ít bị biến chứng hơn và rẻ hơn nếu trình kích hoạt khác có thể hủy bỏ (khôi phục) DELETE một nửa hoạt động - miễn là không có điều nào ở trên áp dụng.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. CHÈN SQL mà không chỉ định cột. Điều gì xảy ra?

  2. django.db.utils.IntegrityError:giá trị khóa trùng lặp vi phạm ràng buộc duy nhất Spirit_category_category_pkey

  3. Sử dụng giá trị trả về từ DELETE cho UPDATE trong Postgres

  4. Hàm cửa sổ SQL với mệnh đề where?

  5. Mảng PostgreSQL của các phần tử mà mỗi phần tử là một khóa ngoại