मुझे ट्रिगर में म्यूटिंग तालिका त्रुटि क्यों नहीं मिल रही है?


11

यह (या कम से कम) ज्ञात था कि आप ट्रिगर के अंदर एक म्यूटिंग टेबल पर डीएमएल स्टेटमेंट का उपयोग नहीं कर सकते हैं। Oracle दस्तावेज़ीकरण का एक अंश :

एक उत्परिवर्तन तालिका एक तालिका है जिसे एक अद्यतन, DELETE, या INSERT विवरण, या एक तालिका द्वारा संशोधित किया जा रहा है जिसे एक DELETE CASCADE बाधा के प्रभाव से अद्यतन किया जा सकता है।

सत्र जिसने ट्रिगरिंग स्टेटमेंट जारी किया है वह एक उत्परिवर्तन तालिका को क्वेरी या संशोधित नहीं कर सकता है। यह प्रतिबंध डेटा के असंगत सेट को देखने से ट्रिगर को रोकता है।

हालाँकि, मैं यह समझ नहीं पा रहा हूँ कि जब मैं insert into empSQL डेवलपर या इंटरनेट कनेक्शन का उपयोग कर रहा हूँ तो यह डेमो ट्रिगर "म्यूटिंग टेबल" त्रुटि के साथ विफल क्यों नहीं हो रहा है :

CREATE OR REPLACE TRIGGER emp_bri   
  BEFORE INSERT ON emp 
    FOR EACH ROW
BEGIN

  SELECT max(id) + 1 INTO :NEW.id FROM emp;
  UPDATE emp SET salary = 5000;

END emp_bri;

प्रविष्टि अगले idमान के साथ सफलतापूर्वक पूर्ण होती है और सभी empरिकॉर्ड को अपडेट करती है। मैं Oracle डेटाबेस 11g एंटरप्राइज़ संस्करण रिलीज़ 11.2.0.1.0 का उपयोग कर रहा हूं। मैंने कंपाउंड ट्रिगर्स के बारे में पढ़ा है लेकिन नमूना उनका उपयोग नहीं करता है।


1
आपके प्रश्न से असंबंधित, लेकिन: अद्वितीय संख्याएँ निर्दिष्ट करने के लिए उपयोग करें select max(id)। बस नहीं है। यह बस गलत है और यह पैमाने पर भी नहीं होगा।
a_horse_with_no_name

हां, मुझे पता है कि :) इस मामले में उदाहरण शायद बहुत अच्छा नहीं है ... अनुक्रम और ट्रिगर्स का उपयोग करके स्वत: अंकन मूल्यों को निश्चित रूप से लागू किया जाना चाहिए।
सेंचुरियन

यह यकीन अजीब है। Btw: यहाँ एक SQLFiddle उदाहरण sqlfiddle.com/#4/9e59f/2
a_horse_with_no_name

जानकारी साझा करने के लिए धन्यवाद, कूल लिंक। पता नहीं ऐसी ओरेकल एसक्यूएल टेस्टिंग वेबसाइट है :)
सेंचुरियन

a_horse_with_no_name: एक और उदाहरण: फिडेल -टेस्ट -2 (सेट वेतन = वेतन + 10)
ypercubeᵀᴹ

जवाबों:


12

एक अपवाद है। जब आप before insertकिसी तालिका पर पंक्ति-स्तर ट्रिगर को परिभाषित करते हैं , और एकल पंक्ति INSERTविवरण जारी करते हैं, तो table is mutatingत्रुटि नहीं उठाई जाएगी। लेकिन अगर आप एक ही तरह के ट्रिगर को परिभाषित करते हैं और एक बहु-पंक्ति INSERTविवरण जारी करते हैं, तो त्रुटि उठाई जाएगी। यहाँ एक उदाहरण है:

SQL> create table TB_TR_TEST(
  2    col1 number,
  3    col2 number
  4  )
  5  ;

Table created

SQL> create or replace trigger TR_TB_TR_TEST
  2  before insert on TB_TR_TEST
  3  for each row
  4  begin
  5    SELECT max(col1) + 1 INTO :NEW.col1
  6      FROM TB_TR_TEST;
  7    UPDATE TB_TR_TEST SET col2 = 5000;
  8  end;
  9  /

Trigger created

यहाँ एक एकल-पंक्ति insertस्टेटमेंट है, जो म्यूटिंग टेबल त्रुटि नहीं बढ़ाएगा:

SQL> insert into TB_TR_TEST(col1, col2) values(1,2);

1 row inserted

SQL> insert into TB_TR_TEST(col1, col2) values(3,5);

1 row inserted

SQL> commit;

Commit complete

यहां एक बहु-पंक्ति सम्मिलित विवरण दिया गया है, जो परिवर्तन तालिका त्रुटि को बढ़ाएगा:

SQL> insert into TB_TR_TEST(col1, col2)
  2    select 1, 2
  3      from dual;

insert into TB_TR_TEST(col1, col2)
  select 1, 2
    from dual

ORA-04091: table HR.TB_TR_TEST is mutating, trigger/function may not see it
ORA-06512: at "HR.TR_TB_TR_TEST", line 2
ORA-04088: error during execution of trigger 'HR.TR_TB_TR_TEST'

यह अपराधी लगता है। क्या आपके पास इस व्यवहार के लिए मैनुअल में एक संदर्भ है?
a_horse_with_no_name 12

@a_horse_with_no_name यदि आपके पास support.oracle.com तक पहुँच है, तो ID 132569.1( ORA-4091 on BEFORE ROW TRIGGER with INSERT .. into SELECT statement) खोजें।
निकोलस क्रासनोव

2
धन्यवाद। यह दिलचस्प है कि यह अपवाद केवल 8i (!) मैनुअल: docs.oracle.com/cd/F49540_01/DOC/server.815/a68003/… (सेक्शन " " म्यूटिंग एंड कांस्ट्रेबिंग टेबल्स ") में प्रलेखित हो सकता है। t वर्तमान नियमावली में उस कथन को
ढूंढें
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.