यदि चाइल्ड टेबल ऐसे डेटा से भरे हुए हैं जो INITIATIVEID
. का संदर्भ देते हैं कॉलम, Oracle को माता-पिता की प्राथमिक कुंजी को बदलकर आपको अनाथ पंक्तियों को बनाने से रोककर प्राथमिक कुंजी मान को स्वचालित रूप से बदलना मुश्किल बना देना चाहिए। इसलिए, उदाहरण के लिए, यदि कोई चाइल्ड टेबल है जिसमें TPM_INITIATIVES
के लिए एक विदेशी कुंजी बाधा है और इस चाइल्ड टेबल में INITIATIVEID
. के साथ एक पंक्ति है 17 में से, आप INITIATIVEID
. को नहीं बदल पाएंगे TPM_INITIAITVES
. में पंक्ति का तालिका जिसका वर्तमान मान 17 है। यदि किसी चाइल्ड तालिका में कोई पंक्ति नहीं है जो TPM_INITIATIVES
में विशेष पंक्ति को संदर्भित करती है तालिका में, आप मान बदल सकते हैं लेकिन, संभवतः, यदि कोई संबंध नहीं हैं, तो प्राथमिक कुंजी मान को बदलना महत्वहीन है क्योंकि यह परिभाषा के अनुसार, डेटा अखंडता समस्या का कारण नहीं बन सकता है। बेशक, आपके पास कोड हो सकता है जो TPM_INITIATIVES
में एक नई पंक्ति सम्मिलित करता है एक नए INITIATIVEID
. के साथ , चाइल्ड टेबल में उन सभी पंक्तियों को बदलें जो नई पंक्ति को संदर्भित करने के लिए पुरानी पंक्ति को संदर्भित करती हैं, फिर पुरानी पंक्ति को संशोधित करें। लेकिन यह किसी भी प्रस्तावित समाधान में नहीं फंसेगा।
यदि आपके एप्लिकेशन ने चाइल्ड टेबल को परिभाषित किया है, लेकिन उपयुक्त विदेशी कुंजी बाधाओं को घोषित नहीं किया है, तो यह समस्या को हल करने का सबसे अच्छा तरीका होगा।
ऐसा कहा जा रहा है कि, एक दृश्य बनाने का अर्नोन का समाधान काम करना चाहिए। आप तालिका का नाम बदलें, मौजूदा तालिका के समान नाम के साथ एक दृश्य बनाएं, और (संभावित रूप से) उस दृश्य पर ट्रिगर के INSTEAD को परिभाषित करें जो कभी भी INITIATIVEID
को अपडेट नहीं करेगा। कॉलम। इसके लिए एप्लिकेशन के अन्य बिट्स में बदलाव की आवश्यकता नहीं होनी चाहिए।
आप टेबल पर ट्रिगर भी परिभाषित कर सकते हैं
CREATE TRIGGER trigger_name
BEFORE UPDATE ON TPM_INITIATIVES
FOR EACH ROW
DECLARE
BEGIN
IF( :new.initiativeID != :old.initiativeID )
THEN
RAISE_APPLICATION_ERROR( -20001, 'Sorry Charlie. You can''t update the initiativeID column' );
END IF;
END;
कोई, निश्चित रूप से, ट्रिगर को अक्षम कर सकता है और अपडेट जारी कर सकता है। लेकिन मैं मान रहा हूं कि आप किसी हमलावर को रोकने की कोशिश नहीं कर रहे हैं, बस कोड का एक छोटा सा टुकड़ा है।
आप कौन से लक्षण देख रहे हैं, इसके विवरण के आधार पर, इस तालिका में कॉलम में परिवर्तनों के इतिहास को लॉग करना अधिक समझ में आता है ताकि आप अनुमान लगाने और छेद को प्लग करने का प्रयास करने के बजाय वास्तव में यह निर्धारित कर सकें कि क्या हो रहा है। -एक - एक करके। इसलिए, उदाहरण के लिए, आप ऐसा कुछ कर सकते हैं
CREATE TABLE TPM_INITIATIVES_HIST (
INITIATIVEID NUMBER NOT NULL,
NAME VARCHAR2(100) NOT NULL,
ACTIVE CHAR(1) NULL,
SORTORDER NUMBER NULL,
SHORTNAME VARCHAR2(100) NULL,
PROJECTTYPEID NUMBER NOT NULL,
OPERATIONTYPE VARCHAR2(1) NOT NULL,
CHANGEUSERNAME VARCHAR2(30),
CHANGEDATE DATE,
COMMENT VARCHAR2(4000)
);
CREATE TRIGGER trigger_name
BEFORE INSERT or UPDATE or DELETE ON TPM_INITIATIVES
FOR EACH ROW
DECLARE
l_comment VARCHAR2(4000);
BEGIN
IF( inserting )
THEN
INSERT INTO tpm_initiatives_hist( INITIATIVEID, NAME, ACTIVE, SORTORDER, SHORTNAME, PROJECTTYPEID,
OPERATIONTYPE, CHANGEUSERNAME, CHANGEDATE )
VALUES( :new.initiativeID, :new.name, :new.active, :new.sortOrder, :new.shortName, :new.projectTypeID,
'I', USER, SYSDATE );
ELSIF( inserting )
THEN
IF( :new.initiativeID != :old.initiativeID )
THEN
l_comment := 'Initiative ID changed from ' || :old.initiativeID || ' to ' || :new.initiativeID;
END IF;
INSERT INTO tpm_initiatives_hist( INITIATIVEID, NAME, ACTIVE, SORTORDER, SHORTNAME, PROJECTTYPEID,
OPERATIONTYPE, CHANGEUSERNAME, CHANGEDATE, COMMENT )
VALUES( :new.initiativeID, :new.name, :new.active, :new.sortOrder, :new.shortName, :new.projectTypeID,
'U', USER, SYSDATE, l_comment );
ELSIF( deleting )
THEN
INSERT INTO tpm_initiatives_hist( INITIATIVEID, NAME, ACTIVE, SORTORDER, SHORTNAME, PROJECTTYPEID,
OPERATIONTYPE, CHANGEUSERNAME, CHANGEDATE )
VALUES( :old.initiativeID, :old.name, :old.active, :old.sortOrder, :old.shortName, :old.projectTypeID,
'D', USER, SYSDATE );
END IF;
END;
फिर आप TPM_INITIATIVES_HIST
query को क्वेरी कर सकते हैं समय के साथ किसी विशेष पंक्ति में किए गए सभी परिवर्तनों को देखने के लिए। तो आप देख सकते हैं कि प्राथमिक कुंजी मान बदल रहे हैं या कोई गैर-कुंजी फ़ील्ड बदल रहा है। आदर्श रूप से, आपके पास अतिरिक्त कॉलम हो सकते हैं जिन्हें आप परिवर्तनों को ट्रैक करने में सहायता के लिए इतिहास तालिका में जोड़ सकते हैं (यानी शायद V$SESSION
से कुछ है। यह उपयोगी हो सकता है)।