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

अन्य तालिका से सबक्वेरी का उपयोग करके बाधाओं को जोड़ना

एक काम-आसपास आप कर सकते हैं एक भौतिक दृश्य बनाना जिसमें "खराब पंक्तियों" की पहचान करने वाली क्वेरी हो।

create table messages(
   message_id  number       not null
  ,sender_id   varchar2(20) not null
  ,primary key(message_id)
);

create table receivers(
   message_id  number       not null
  ,receiver_id varchar2(20) not null
  ,primary key(message_id,receiver_id)
  ,foreign key(message_id) references messages(message_id)
);

create materialized view log 
    on receivers with primary key, rowid including new values;

create materialized view log 
    on messages  with primary key, rowid (sender_id) including new values;

create materialized view mv 
refresh fast on commit
as
select count(*) as bad_rows 
  from messages  m
  join receivers r using(message_id)
 where m.sender_id = r.receiver_id;

alter materialized view mv
  add constraint dont_send_to_self check(bad_rows = 0);

आइए अब कुछ पंक्तियों को सम्मिलित करने का प्रयास करें:

SQL> insert into messages(message_id, sender_id)    values(1, 'Ronnie');
1 row created.

SQL> insert into receivers(message_id, receiver_id) values(1, 'Mayank Sharma');
1 row created.

SQL> commit;
Commit complete.

वह ठीक से गया। आइए अब अपने आप को एक संदेश भेजें:

SQL> insert into messages(message_id, sender_id) values(2, 'Ronnie');    
1 row created.

SQL> insert into receivers(message_id, receiver_id) values(2, 'Ronnie');    
1 row created.

SQL> commit;
commit
*
ERROR at line 1:
ORA-12008: error in materialized view refresh path
ORA-02290: check constraint (RNBN.DONT_SEND_TO_SELF) violated

संपादित करें, अधिक स्पष्टीकरण: ठीक है, यह क्वेरी (भौतिक रूप से देखने की परिभाषा में), उन सभी संदेशों की पहचान और गणना करती है जो स्वयं को भेजे जा रहे हैं। यानी, वे सभी पंक्तियाँ जो उल्लंघन करती हैं आपने जो नियम बताया है।

select count(*) as bad_rows 
  from messages  m
  join receivers r using(message_id)
 where m.sender_id = r.receiver_id;

तो क्वेरी को हर समय 0 पंक्तियों को वापस करना चाहिए, है ना? भौतिक दृश्य क्या करता है, जब कोई भी टेबल messages के विरुद्ध डीएमएल ऑपरेशन करता है तो स्वयं को रीफ्रेश करना होता है या receivers . तो सिद्धांत रूप में, यदि कोई व्यक्ति स्वयं को एक संदेश सम्मिलित करता है, तो क्वेरी वापस आ जाएगी bad_rows = 1 . लेकिन, मैंने भौतिक दृश्य पर एक बाधा भी शामिल की है, जिसमें कहा गया है कि कॉलम bad_rows के लिए एकमात्र अनुमत मान है 0 है। Oracle आपको ऐसा कोई भी लेन-देन नहीं करने देगा जो एक और मूल्य देता हो।

इसलिए यदि आप इन्सर्ट स्टेटमेंट की दूसरी जोड़ी को देखते हैं, तो आप देख सकते हैं कि मैंने रिसीवर्स में गलत रो डालने में कामयाबी हासिल की है, लेकिन जब मैं कमिट करने की कोशिश करता हूं तो ओरेकल एक बाधा उल्लंघन देता है।




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. डॉकर के साथ PHP7.0-FPM:गतिशील पुस्तकालय लोड करने में असमर्थ OCI8

  2. मैं Oracle की मैन्युअल अनइंस्टॉल कैसे करूँ?

  3. शून्य मान की अनुमति देने के लिए ORACLE बाधा, IF

  4. Oracle SQL:|| . के साथ CHR() फ़ंक्शन का उपयोग करना CONCATENATE

  5. Oracle SQL क्वेरी में नवीनतम का चयन करें