Điều này nên làm điều đó:
CREATE OR REPLACE FUNCTION device_bid_modifiers_count_per()
RETURNS TRIGGER AS
$func$
DECLARE
devices_count int := device_types_count();
table_name regclass := TG_ARGV[0];
column_name text := TG_ARGV[1];
BEGIN
LOCK TABLE device_types IN EXCLUSIVE MODE;
EXECUTE format('LOCK TABLE %s IN EXCLUSIVE MODE', table_name);
IF TG_OP = 'DELETE' THEN
PERFORM validate_bid_modifiers_count(table_name
, column_name
, (row_to_json(OLD) ->> column_name)::bigint
, devices_count);
ELSE
PERFORM validate_bid_modifiers_count(table_name
, column_name
, (row_to_json(NEW) ->> column_name)::bigint
, devices_count);
END IF;
RETURN NEW;
END
$func$ LANGUAGE plpgsql;
Nguyên nhân ngay lập tức cho thông báo lỗi là SELECT
bên ngoài . Nếu không có đích, bạn cần thay thế nó bằng PERFORM
trong plpgsql. Nhưng PERFORM
bên trong trong chuỗi truy vấn được chuyển tới EXECUTE
cũng sai. PERFORM
là một lệnh plpgsql, không hợp lệ trong một chuỗi SQL được chuyển tới EXECUTE
, mong đợi mã SQL. Bạn phải sử dụng SELECT
ở đó. Cuối cùng là OLD
và NEW
không hiển thị bên trong EXECUTE
và mỗi người sẽ nêu ra một ngoại lệ của riêng họ theo cách bạn đã có. Tất cả các vấn đề được khắc phục bằng cách bỏ EXECUTE
.
Một cách đơn giản và nhanh chóng để nhận giá trị của tên cột động từ các loại hàng OLD
và NEW
:truyền tới json
, sau đó bạn có thể tham số hóa tên khóa như đã trình bày. Sẽ đơn giản và nhanh hơn một chút so với phương án thay thế bằng SQL động - điều này cũng có thể xảy ra, như:
...
EXECUTE format('SELECT validate_bid_modifiers_count(table_name
, column_name
, ($1.%I)::bigint
, devices_count)', column_name)
USING OLD;
...
Có liên quan:
Bên cạnh:Không chắc chắn tại sao bạn cần những ổ khóa nặng.
Bên cạnh 2:Thay vào đó, hãy cân nhắc viết một hàm kích hoạt riêng biệt cho từng trình kích hoạt. DDL ồn ào hơn, nhưng đơn giản hơn và thực thi nhanh hơn.