Oracle
 sql >> डेटाबेस >  >> RDS >> Oracle

प्राथमिक कुंजी बाधा जैसे ट्रिगर कैसे बनाएं?

सिर्फ इसलिए कि आप इसे विफल देखने के इरादे से लगते हैं, और एपीसी के बिंदुओं से कुछ भी दूर नहीं करना चाहते हैं, यह पहली नज़र में तब तक काम करता है जब तक यह before है। ट्रिगर:

create table t42 (id number);

create trigger trig42
before insert or update on t42
for each row
declare
  c number;
begin
  if :new.id is null then
    raise_application_error(-20001, 'ID is null');    
  end if;
  select count(*) into c from t42 where id = :new.id;
  if c > 0 then
    raise_application_error(-20002, 'ID is not unique');
  end if;
end;
/

यह संकलित करता है और यदि आप डेटा सम्मिलित करते हैं तो आपको वह व्यवहार मिलता है जो आप चाहते हैं:

insert into t42 values (1);

1 rows inserted.

insert into t42 values (1);

Error starting at line 20 in command:
insert into t42 values (1)
Error report:
SQL Error: ORA-20002: ID is not unique
ORA-06512: at "STACKOVERFLOW.TRIG42", line 9
ORA-04088: error during execution of trigger 'STACKOVERFLOW.TRIG42'

insert into t42 values (null);

Error starting at line 22 in command:
insert into t42 values (null)
Error report:
SQL Error: ORA-20001: ID is null
ORA-06512: at "STACKOVERFLOW.TRIG42", line 5
ORA-04088: error during execution of trigger 'STACKOVERFLOW.TRIG42'

select * from t42;

        ID
----------
         1 

ऐसा लगता है कि आप जो चाहते हैं वह करते हैं। लेकिन तब नहीं जब आपके पास एक से अधिक सत्र हों। मैंने इस सत्र में प्रतिबद्ध नहीं किया है; दूसरे सत्र में मैं यह कर सकता हूं:

insert into t42 values (1);

1 row created.

select * from t42;

        ID
----------
         1

1 row selected.

हम्म, यह अजीब है। ठीक है, शायद इसे स्थगित कर दिया गया है... आइए उन दोनों को प्रतिबद्ध करें:

commit;

select * from t42;
        ID
----------
         1
         1

2 rows selected.

उफ़। एक बार सत्र दूसरे सत्र का अनकमिटेड डेटा नहीं देख सकता है, इसलिए यह कभी काम नहीं करेगा।

साथ ही, जब हम एक ही कथन में कई पंक्तियाँ सम्मिलित करते हैं, तो परिवर्तनशील तालिका समस्या स्वयं प्रदर्शित होती है:

SQL> insert into t42 select level+1 from dual connect by level <= 5; 
insert into t42 select level+1 from dual connect by level <= 5
            *
ERROR at line 1:
ORA-04091: table STACKOVERFLOW.T42 is mutating, trigger/function may not see it
ORA-06512: at "STACKOVERFLOW.TRIG42", line 7
ORA-04088: error during execution of trigger 'STACKOVERFLOW.TRIG42'


SQL> 

डबल ओह।

यहां तक ​​कि after . के साथ भी ट्रिगर और एक पैकेज उत्परिवर्तन तालिका समस्या के आसपास काम करने के लिए, आपको अभी भी यह समस्या होगी (मुझे लगता है), जब तक कि आप प्रत्येक सम्मिलन या अद्यतन के लिए पूरी तालिका को लॉक नहीं करते। जैसा कि एपीसी ने कहा है कि बाधा डेटाबेस के आंतों में गहराई से लागू होती है, इस स्तर पर नहीं।

तब नहीं जब आपके पास एक से अधिक सत्र हों, नहीं। और यहां तक ​​कि एक सत्र के भीतर, जब तक कि आपके पास कॉलम पर कोई अनुक्रमणिका नहीं है, प्रदर्शन count(*) के रूप में स्केल नहीं होगा उत्तरोत्तर धीमी होती जाएगी। और यदि आपके पास कोई अनुक्रमणिका है, तो क्यों न इसे पहले स्थान पर एक अद्वितीय अनुक्रमणिका बनाया जाए?

अंत में, ट्रिगर डिज़ाइन दिशानिर्देश से :



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. तालिका कॉलम प्रारूप में ओरेकल कॉलम नाम लौटाएं?

  2. एचक्यूएल क्वेरी में कंडीटोन के साथ शामिल हों?

  3. एसएसआईएस में ओरेकल से SQL2005 डेटाटाइम फ़ील्ड ओवरफ्लो हो जाता है

  4. कर्सर से एक में संघ डेटा

  5. Oracle JDBC बैच अद्यतन पंक्तियाँ हमेशा -2 (विवरण.SUCCESS_NO_INFO) प्रभावित होती हैं