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

Cách tránh cuộc gọi kích hoạt vòng lặp trong PostgreSQL 9.2.1

Bạn có thể làm điều này với trình kích hoạt tiêu chuẩn BEFORE UPDATE OF ... ON ... .
Hướng dẫn về CREATE TRIGGER thông báo:

Trình kích hoạt sẽ chỉ kích hoạt nếu ít nhất một trong các cột được liệt kê được đề cập làm mục tiêu của lệnh UPDATE.

Và xa hơn nữa:

Một trình kích hoạt dành riêng cho cột (một trình kích hoạt được xác định bằng cách sử dụng UPDATE OF column_namesyntax) sẽ kích hoạt khi bất kỳ cột nào của nó được liệt kê là mục tiêu trong danh sách SET của lệnhUPDATE. Giá trị của cột có thể thay đổi ngay cả khi trình kích hoạt không được kích hoạt, vì các thay đổi được thực hiện đối với nội dung của cột bởi trình kích hoạt TRƯỚC KHI CẬP NHẬT không được xem xét.

Tôi nhấn mạnh đậm. Vì vậy, không có vòng lặp vô hạn, bởi vì các bản cập nhật bên trong trình kích hoạt không gọi trình kích hoạt khác.

Trường hợp thử nghiệm

Tạo bảng kiểm tra (đơn giản hóa, không có các hàng không liên quan):

CREATE TABLE soil_samples (
  pgid SERIAL PRIMARY KEY

 ,utm_zone integer
 ,utm_easting integer
 ,utm_northing integer

 ,wgs84_longitude double precision
 ,wgs84_latitude double precision

 ,yt_albers_geom double precision
);

Trình kích hoạt giả cho yêu cầu đầu tiên của bạn:

Khi cập nhật xong cho utm_zone , utm_easting hoặc utm_northing , rồi đến wgs_84_latitude , wgs84_longitudeyt_albers_geom được cập nhật bởi một trình kích hoạt.

CREATE OR REPLACE FUNCTION trg_upbef_utm()  RETURNS trigger AS
$func$
BEGIN
   NEW.wgs84_latitude  := NEW.wgs84_latitude + 10;
   NEW.wgs84_longitude := NEW.wgs84_longitude + 10;
   NEW.yt_albers_geom  := NEW.yt_albers_geom + 10;

   RETURN NEW;
END
$func$ LANGUAGE plpgsql;

CREATE TRIGGER upbef_utm
BEFORE UPDATE OF utm_zone, utm_easting, utm_northing ON soil_samples
FOR EACH ROW
WHEN (NEW.utm_zone     IS DISTINCT FROM OLD.utm_zone    OR
      NEW.utm_easting  IS DISTINCT FROM OLD.utm_easting OR
      NEW.utm_northing IS DISTINCT FROM OLD.utm_northing)  -- optional
EXECUTE PROCEDURE trg_upbef_utm();

WHEN mệnh đề là tùy chọn. Ngăn trình kích hoạt kích hoạt khi không có giá trị nào thực sự thay đổi.

Trình kích hoạt giả cho yêu cầu thứ hai của bạn:

Khi cập nhật xong cho wgs84_latitude hoặc wgs84_longitude , sau đó tất cả các u tm_ các trường được cập nhật, cũng như yt_albers_geom .

CREATE OR REPLACE FUNCTION trg_upbef_wgs84()  RETURNS trigger AS
$func$
BEGIN
   NEW.utm_zone       := NEW.utm_zone + 100;
   NEW.utm_easting    := NEW.utm_easting + 100;
   NEW.utm_northing   := NEW.utm_northing + 100;
   NEW.yt_albers_geom := NEW.yt_albers_geom + 100;

   RETURN NEW;
END
$func$ LANGUAGE plpgsql;

CREATE TRIGGER upbef_wgs84
 BEFORE UPDATE OF wgs84_latitude, wgs84_longitude ON soil_samples
 FOR EACH ROW
 WHEN (NEW.wgs84_latitude  IS DISTINCT FROM OLD.wgs84_latitude OR
       NEW.wgs84_longitude IS DISTINCT FROM OLD.wgs84_longitude)  -- optional
 EXECUTE PROCEDURE trg_upbef_wgs84();

Kích hoạt cho yêu cầu thứ ba dọc theo những dòng này ...

Kiểm tra

INSERT INTO soil_samples VALUES (1, 1,1,1, 2,2, 3) RETURNING *;

Kích hoạt upbef_utm :cập nhật trống, không có gì xảy ra:

UPDATE soil_samples SET utm_zone = 1 RETURNING *;

Cập nhật với thay đổi thực tế:Trình kích hoạt thứ hai upbef_wgs84 sẽ không kích hoạt vào UPDATE OF utm_zone !

UPDATE soil_samples SET utm_zone = 0 RETURNING *;

Kích hoạt upbef_wgs84 :

UPDATE soil_samples SET wgs84_latitude = 0 RETURNING *;

-> Bản trình diễn SQLfiddle.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Trạng thái hiện tại của quản lý sao lưu mã nguồn mở cho PostgreSQL

  2. Truy vấn Rails 4 LIKE - ActiveRecord thêm dấu ngoặc kép

  3. Cách kết nối với Postgres qua Node.js

  4. Bảo vệ sar (và cách cấu hình nó)

  5. Tính tuổi theo năm trong PostgreSQL