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

Oracle - Sự cố khi tạo trình kích hoạt cập nhật bảng khác

Một số vấn đề không theo thứ tự cụ thể.

Trước tiên, trong nội dung của trình kích hoạt cấp hàng, bạn cần sử dụng :new:old để tham khảo các bản ghi mới và cũ. Dấu hai chấm đứng đầu là cần thiết. Vì vậy, WHERE của bạn mệnh đề cần phải được

WHERE PROJECTID = :new.PROJECTID

Thứ hai, nếu bạn đang chạy CREATE TRIGGER của mình trong SQL * Plus, bạn có thể nhận được danh sách các lỗi và cảnh báo bằng cách sử dụng SHOW ERRORS lệnh, tức là

SQL> show errors

Bạn cũng có thể truy vấn DBA_ERRORS bảng (hoặc ALL_ERRORS hoặc USER_ERRORS tùy thuộc vào mức đặc quyền của bạn) nhưng đó không phải là điều bạn thường cần sử dụng.

Thứ ba, giả sử các lỗi cú pháp được sửa, bạn sẽ nhận được một đột biến lỗi bảng nếu bạn sử dụng logic này. Trình kích hoạt cấp hàng trên bảng A (TPM_TRAININGPLAN trong trường hợp này) không thể truy vấn bảng A vì bảng có thể ở trạng thái không nhất quán. Bạn có thể giải quyết vấn đề đó, như Tim đã trình bày trong bài viết của anh ấy, bằng cách tạo một gói có tập hợp, khởi tạo tập hợp đó trong trình kích hoạt câu lệnh trước, điền dữ liệu trong tập hợp vào trình kích hoạt cấp hàng và sau đó xử lý các hàng đã sửa đổi trong một kích hoạt câu lệnh sau. Tuy nhiên, đó là một lượng phức tạp đáng kể để thêm vào hệ thống, vì bạn sẽ phải quản lý nhiều đối tượng khác nhau.

Nói chung, tốt hơn hết bạn nên triển khai logic này như một phần của bất kỳ API nào bạn sử dụng để thao tác TPM_TRAININGPLAN bàn. Nếu đó là một thủ tục được lưu trữ, sẽ có ý nghĩa hơn nhiều nếu đặt logic để cập nhật TPM_PROJECT trong thủ tục được lưu trữ đó thay vì đặt nó trong một trình kích hoạt. Nổi tiếng là khó khăn khi cố gắng gỡ lỗi một ứng dụng có nhiều logic được nhúng trong các trình kích hoạt vì điều đó khiến các nhà phát triển rất khó theo dõi chính xác các hoạt động đang được thực hiện. Ngoài ra, bạn có thể xóa TRAININGDELIVERYSTART cột từ TPM_PROJECT bảng và chỉ cần tính ngày bắt đầu tối thiểu trong thời gian chạy.

Thứ tư, nếu trình kích hoạt của bạn kích hoạt khi chèn, cập nhật và xóa, bạn không thể chỉ tham khảo :new các giá trị. :new có giá trị cho các lần chèn và cập nhật nhưng nó sẽ là NULL nếu bạn đang xóa. :old hợp lệ để xóa và cập nhật nhưng sẽ là NULL nếu bạn đang thực hiện chèn. Điều đó có nghĩa là bạn có thể cần phải có logic dọc theo dòng (tham khảo giải pháp gói của Tim)

BEGIN
  IF inserting 
  THEN
    trigger_api.tab1_row_change(p_id => :new.projectid, p_action => 'INSERT');
  ELSIF updating
  THEN
    trigger_api.tab1_row_change(p_id => :new.projectid, p_action => 'UPDATE');
  ELSIF deleting
  THEN
    trigger_api.tab1_row_change(p_id => :old.projectid, p_action => 'DELETE');
  END IF;
END;


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Làm cách nào để sử dụng FOR UPDATE với một JOIN trên Oracle?

  2. Java:Io ngoại lệ:Bộ điều hợp mạng không thể thiết lập kết nối

  3. Đặt thời gian hết hạn / gia hạn mật khẩu người dùng oracle

  4. Làm thế nào để sắp xếp theo số đầu tiên với truy vấn SQL của Oracle?

  5. Buộc SELECT bên ngoài không thành công nếu SELECT bên trong chứa số nhận dạng không hợp lệ