Tôi nghĩ rằng tôi không đồng ý với mô tả của bạn về những gì trình kích hoạt đang cố gắng thực hiện. Đối với tôi, có vẻ như nó được dùng để thực thi quy tắc kinh doanh này:Đối với giá trị agiven của t1_appnt_event, chỉ một hàng có thể có giá trị không phải NULL củat1_prnt_t1_pk tại một thời điểm. (Không quan trọng nếu chúng có cùng giá trị trong cột thứ hai hay không.)
Điều thú vị là nó được xác định cho UPDATE OF t1_appnt_event nhưng không cho cột khác, vì vậy tôi nghĩ ai đó có thể phá vỡ quy tắc bằng cách cập nhật cột thứ hai, trừ khi có một trình kích hoạt riêng cho cột đó.
Có thể có một cách bạn có thể tạo chỉ mục dựa trên chức năng thực thi quy tắc này để bạn có thể loại bỏ hoàn toàn trình kích hoạt. Tôi đã nghĩ ra một cách nhưng nó đòi hỏi một số giả định:
- Bảng có khóa chính dạng số
- Khóa chính và t1_prnt_t1_pk luôn là số dương
Nếu những giả định này là đúng, bạn có thể tạo một hàm như sau:
dev> create or replace function f( a number, b number ) return number deterministic as
2 begin
3 if a is null then return 0-b; else return a; end if;
4 end;
và một chỉ mục như thế này:
CREATE UNIQUE INDEX my_index ON my_table
( t1_appnt_event, f( t1_prnt_t1_pk, primary_key_column) );
Vì vậy, các hàng trong đó cột PMNT là NULL sẽ xuất hiện trong chỉ mục với nghịch đảo của khóa chính là giá trị thứ hai, vì vậy chúng sẽ không bao giờ xung đột với nhau. Các hàng mà nó không phải là NULL sẽ sử dụng giá trị thực (dương) của cột. Cách duy nhất bạn có thể gặp phải vi phạm ràng buộc là nếu hai hàng có cùng giá trị không phải NULL trong cả hai cột.
Điều này có lẽ quá "thông minh", nhưng nó có thể giúp bạn giải quyết vấn đề của mình.
Cập nhật từ Paul Tomblin:Tôi đã cập nhật ý tưởng ban đầu mà tôi đưa ra trong phần nhận xét:
CREATE UNIQUE INDEX cappec_ccip_uniq_idx
ON tbl1 (t1_appnt_event,
CASE WHEN t1_prnt_t1_pk IS NOT NULL THEN 1 ELSE t1_pk END);