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

Vòng lặp vô tận trong chức năng kích hoạt

ELSE nhánh có thể được đơn giản hóa hoàn toàn. Nhưng một vài thứ nữa không hiệu quả / không chính xác / nguy hiểm:

CREATE OR REPLACE FUNCTION sample_trigger_func()
  RETURNS TRIGGER AS
$func$
BEGIN
   IF TG_OP = 'DELETE' THEN
      RAISE INFO 'OLD: %', OLD.name;

      EXECUTE format('INSERT INTO %I SELECT ($1).*', TG_TABLE_NAME || '_deletes')
      USING OLD #= hstore('{mod_op, mod_datetime}'::text[]
                         , ARRAY[left(TG_OP, 1), now()::text]);
      RETURN OLD;
   ELSE  -- insert, update
      NEW.mod_op       := left(TG_OP, 1);
      NEW.mod_datetime := now();

      RETURN NEW;
   END IF;
END
$func$  LANGUAGE plpgsql;
  • Trong ELSE nhánh chỉ cần gán cho NEW trực tiếp. Không cần thêm SQL động - sẽ kích hoạt lại cùng một trình kích hoạt gây ra một vòng lặp vô tận. Đó là lỗi chính.

  • TRỞ LẠI MỚI; bên ngoài IF cấu trúc sẽ phá vỡ chức năng kích hoạt của bạn cho DELETE , kể từ NEW không được chỉ định cho DELETE.

  • Một tính năng chính là sử dụng hstore và toán tử hstore # = để thay đổi động hai trường đã chọn của loại hàng nổi tiếng - đó là ẩn số tại thời điểm viết mã. Bằng cách này, bạn không làm xáo trộn OLD gốc giá trị, có thể có tác dụng phụ đáng ngạc nhiên nếu bạn có nhiều tác nhân gây ra chuỗi sự kiện hơn.

    OLD #= hstore('{mod_op, mod_datetime}'::text[]
                 , ARRAY[left(TG_OP, 1), now()::text]);
    

    Mô-đun bổ sung hstore phải được cài đặt. Chi tiết:

    Sử dụng hstore (text [], text []) biến thể ở đây để tạo hstore giá trị với nhiều trường nhanh chóng.

  • Toán tử gán trong plpgsql là := :

  • Lưu ý rằng tôi đã sử dụng tên cột mod_datetime thay vì mod_date gây hiểu lầm , vì cột rõ ràng là một dấu thời gian và không phải là ngày .

Tôi đã thêm một số cải tiến khác trong khi ở đó. Và bản thân trình kích hoạt sẽ trông như thế này:

CREATE TRIGGER insupdel_bef
BEFORE INSERT OR UPDATE OR DELETE ON table_name
FOR EACH ROW EXECUTE PROCEDURE sample_trigger_func();

SQL Fiddle.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Postgres - Làm cách nào để tự động gọi ST_SetSRID (ST_MakePoint (lng, lat), 4326) trên chèn?

  2. Cách thực thi nhiều phép nối với các tham số khác nhau trong một truy vấn

  3. Thiết lập Django và PostgreSQL trên hai phiên bản EC2 khác nhau

  4. Không thể chèn JSON từ PostgreSQL vàoasticsearch. Gặp lỗi - "Ngoại lệ khi thực hiện truy vấn JDBC"

  5. Cấp đặc quyền cho một cơ sở dữ liệu cụ thể trong PostgreSQL