2016-03-30 24 views
7

Tôi thêm PRAGMA RESTRICT_REFERENCES vào quy trình trong gói (ví dụ: RNPS). Việc thực hiện thủ tục đó chèn một hàng vào một bảng.RESTRICT_REFERENCES và trình kích hoạt

Bảng đó có trình kích hoạt chèn trước. mà kích hoạt đọc một biến từ một gói và đặt nó: new.my_column.

Tôi có thể biên dịch thân gói mà không gặp vấn đề gì, mặc dù có vẻ như nó thực sự đang đọc các giá trị từ một biến gói.

Khi tôi thực hiện quy trình, nó thực sự hoạt động. Nhưng đây là sự phát triển của sự phát triển, nơi thường không có nhiều kết nối đồng thời. Tôi sợ rằng điều này có thể thất bại trong môi trường sản xuất.

Vì vậy, tôi có nên lo lắng hay điều này thực sự hiệu quả?

Ví dụ mã:

CREATE TABLE MY_TABLE 
(
    ID VARCHAR2(20) NOT NULL 
, USER_ID VARCHAR2(50) 
, CONSTRAINT MY_TABLE_PK PRIMARY KEY 
    (
    ID 
) 
    ENABLE 
); 

CREATE OR REPLACE PACKAGE PUSER IS 

    PROCEDURE saveUser(
      pUserId VARCHAR2 
     ); 
    PRAGMA RESTRICT_REFERENCES (saveUser, WNDS, RNDS, RNPS); 

    FUNCTION getUser RETURN VARCHAR2; 
    PRAGMA RESTRICT_REFERENCES (getUser, WNDS, RNDS, WNPS); 

END PUSER; 

CREATE OR REPLACE PACKAGE BODY PUSER AS 

    userId VARCHAR2(50); 

    PROCEDURE saveUser(
      pUserId VARCHAR2 
     ) IS 
    BEGIN 
     userId := pUserId; 
    END saveUser; 

    FUNCTION getUser RETURN VARCHAR2 IS 
    BEGIN 
     RETURN userId; 
    END getUser; 

END PUSER; 


CREATE OR REPLACE PACKAGE MY_PACKAGE IS 

    PROCEDURE insertMyTable(
      pId VARCHAR2 
     ); 
    PRAGMA RESTRICT_REFERENCES (insertMyTable, RNPS); 

END MY_PACKAGE; 

CREATE OR REPLACE PACKAGE BODY MY_PACKAGE AS 

    PROCEDURE insertMyTable(
      pId VARCHAR2 
     ) IS 
    BEGIN 
     INSERT INTO MY_TABLE(id) VALUES(pId); 
    END insertMyTable; 
END MY_PACKAGE; 

CREATE OR REPLACE TRIGGER MY_TABLE_TRIGGER 
BEFORE INSERT ON MY_TABLE FOR EACH ROW 
DECLARE 
BEGIN 
    :new.USER_ID := PUSER.getUser; 
END MY_TABLE_TRIGGER; 

Chỉnh sửa: Tôi biết rằng RESTRICT_REFERENCES bị phản đối, nhưng biết điều này vẫn sẽ có ích cho mã đã tồn tại.

+1

Ngoài việc nó hoạt động, bạn biết ['restrict_references' bị phản đối] (http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/restrictreferences_pragma.htm#LNPLS01339)? –

+0

@AlexPoole Vâng, tôi đã học được rằng trong khi tìm kiếm về chủ đề này. Nhưng chúng tôi thực sự phải thêm trình kích hoạt vào một số bảng và các gói đã được triển khai. Nếu tôi có, tôi sẽ thay đổi tất cả các định nghĩa gói, nhưng tôi đã hy vọng để tránh điều đó. – Pablo

+0

Thay đổi chúng để loại bỏ các pragmas (mà lá bạn, nơi bạn đang thực sự); hoặc thay đổi 'my_package.insertMyTable' để gọi trực tiếp' puser.getUser', điều này sẽ không biên dịch được vì xác nhận? Bạn lo lắng điều gì sẽ thất bại - rằng pragma bị âm thầm vi phạm, hoặc sẽ gây ra lỗi thời gian chạy (nhưng nó được kiểm tra tại thời gian biên dịch), hoặc tác dụng phụ bạn không mong đợi (nhưng trạng thái gói là cụ thể theo phiên) ? Trừ khi bạn đang thực hiện song song tôi không thấy một vấn đề thực sự; nhưng đó là một thời gian dài kể từ khi tôi đã sử dụng pragma này. –

Trả lời

1

RNPS chỉ hữu ích cho các hàm khi nó cho trình biên dịch biết rằng giá trị trả về của hàm sẽ không thay đổi giữa các cuộc gọi nếu không có trạng thái gói (hoặc trạng thái cơ sở dữ liệu cho các pragma khác). Nó cho phép lưu vào bộ nhớ đệm, nhưng theo cách ngầm hơn với RESULT_CACHE hoặc DETERMINISTIC (hiện giờ là cách ưu tiên để thông báo cho trình tối ưu hóa những gì mong đợi).

Vì bạn sử dụng nó trên một quy trình, nó không thực sự quan trọng. Bạn có thể tiến hành một cách an toàn mà không thay đổi thông số kỹ thuật của gói. Tuy nhiên, kể từ khi bạn (hoặc người kế nhiệm của bạn) có thể tự hỏi mình cùng một câu hỏi một năm kể từ bây giờ, bạn cũng có thể thay đổi các gói ngay bây giờ trong khi bạn đang ở đó.

Các vấn đề liên quan