2016-03-30 11 views
7

मैं एक पैकेज में एक प्रक्रिया (उदाहरण के लिए, आरएनपीएस) में एक PRAGMA RESTRICT_REFERENCES जोड़ता हूं। वह प्रक्रिया कार्यान्वयन एक तालिका में एक पंक्ति डालता है।RESTRICT_REFERENCES और ट्रिगर्स

उस तालिका में पहले से सम्मिलित ट्रिगर है। कि ट्रिगर एक चर से एक चर को पढ़ता है और इसे डालता है: new.my_column।

मैं बिना किसी समस्या के पैकेज पैकेज को संकलित कर सकता हूं, भले ही ऐसा लगता है कि यह वास्तव में एक पैकेज चर से मूल्यों को पढ़ रहा है।

जब मैं प्रक्रिया निष्पादित करता हूं, तो यह वास्तव में काम करता है। लेकिन यह विकास eviroment है, जहां आमतौर पर कोई एक साथ कनेक्शन नहीं हैं। मुझे डर है कि यह उत्पादन वातावरण में असफल हो सकता है।

तो, क्या मुझे चिंतित होना चाहिए, या यह वास्तव में काम करेगा?

उदाहरण कोड:

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; 

संपादित करें: मुझे पता है कि RESTRICT_REFERENCES हटा दिया गया है, लेकिन यह जानते हुए भी अभी भी पहले से ही विद्यमान कोड के लिए उपयोगी होगा।

+1

एक तरफ है कि क्या यह काम करता है से, तुम्हें पता है [ 'restrict_references' हटा दिया गया है] (http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/restrictreferences_pragma.htm#LNPLS01339)? –

+0

@AlexPoole हां, मैंने सीखा कि इस विषय के बारे में खोज करते समय। लेकिन हमें वास्तव में कई तालिकाओं में ट्रिगर्स जोड़ना होगा, और संकुल पहले ही कार्यान्वित किए गए हैं। अगर मुझे करना है, तो मैं सभी पैकेज परिभाषाओं को बदल दूंगा, लेकिन मैं इससे बचने की उम्मीद कर रहा था। – Pablo

+0

उन्हें प्रागमाओं को हटाने के लिए बदलें (जो आपको छोड़ देता है जहां आप वास्तव में हैं); या 'my_package.insertMyTable' को' puser.getUser' को सीधे कॉल करने के लिए बदलें, जो दावा के कारण संकलित करने में विफल रहेगा? आप क्या चिंतित हैं असफल हो जाएंगे - कि प्रगति का चुपचाप उल्लंघन किया जाता है, या रन-टाइम त्रुटि का कारण बनता है (लेकिन यह संकलन समय पर चेक किया गया है), या एक दुष्प्रभाव जो आप उम्मीद नहीं कर रहे हैं (लेकिन पैकेज स्थिति सत्र-विशिष्ट है) ? जब तक आप समानांतर में निष्पादित नहीं कर रहे हैं, मुझे एक वास्तविक समस्या दिखाई नहीं दे रही है; लेकिन यह एक लंबा समय है क्योंकि मैंने इस प्रज्ञा का उपयोग किया है। –

उत्तर

1

RNPS केवल कार्यों के लिए उपयोगी है क्योंकि यह कंपाइलर को बताता है कि किसी फ़ंक्शन का रिटर्न वैल्यू कॉल के बीच नहीं बदलेगा यदि इस बीच कोई पैकेज स्थिति (या अन्य प्रोग्राम्स के लिए डेटाबेस स्थिति) में बदलाव नहीं किया गया है। यह कैशिंग के लिए अनुमति देता है, लेकिन RESULT_CACHE या DETERMINISTIC (जो अब आशावादी को बताने के लिए पसंदीदा तरीका है) की तुलना में अधिक अंतर्निहित तरीके से।

चूंकि आप इसे किसी प्रक्रिया पर उपयोग करते हैं, इससे कोई फर्क नहीं पड़ता। आप पैकेज विनिर्देशों को बदलने के बिना सुरक्षित रूप से आगे बढ़ सकते हैं। हालांकि, चूंकि आप (या आपका उत्तराधिकारी) अब से एक ही प्रश्न पूछ सकते हैं, तो आप इस समय पैकेज को बदल सकते हैं।

संबंधित मुद्दे