डेटाबेस ट्रिगर

डेटाबेस ट्रिगर प्रक्रियात्मक कोड है जो किसी विशेष सारणी (डेटाबेस) या डेटाबेस में देखने (डेटाबेस) पर कुछ प्रोग्राम (कंप्यूटिंग) का उत्तर में स्वचालित रूप से निष्पादित करता है। ट्रिगर का उपयोग अधिकतम डेटाबेस पर जानकारी की डेटाबेस अखंडता को बनाए रखने के लिए किया जाता है। उदाहरण के लिए, जब कर्मचारियों की सारणी में नया रिकॉर्ड (नए कार्यकर्ता का प्रतिनिधित्व) सम्मिलित किया जाता है, अवकाश एवं वेतन की सारणी में भी नए रिकॉर्ड बनाए जाने चाहिए। ट्रिगर का उपयोग ऐतिहासिक डेटा लॉग करने के लिए भी किया जा सकता है, उदाहरण के लिए कर्मचारियों के पूर्व वेतन पर दृष्टि रखने के लिए किया जाता है।

डीबीएमएस में ट्रिगर
नीचे कुछ लोकप्रिय डीबीएमएस समर्थन ट्रिगर्स के विवरण की श्रृंखला दी गई है।

आकाशवाणी
डेटा संशोधित होने पर उस अग्नि प्रकट होने को (एवं पीएल/एसक्यूएल कोड को निष्पादित) ट्रिगर करने के अतिरिक्त, आकाशवाणी डाटाबेस उस ट्रिगर का समर्थन करता है जब स्कीमा-स्तरीय ऑब्जेक्ट्स (अर्थात, टेबल) संशोधित होते हैं और जब उपयोगकर्ता लॉगऑन या लॉगऑफ़ ईवेंट होते हैं।

स्कीमा-लेवल ट्रिगर्स

 * सृष्टि के पश्चात
 * ऑल्टर से पूर्व
 * आल्टर के पश्चात
 * ड्राप से पूर्व
 * ड्राप के पश्चात
 * चिह्नित से पूर्व

चार मुख्य प्रकार के ट्रिगर हैं:
 * 1) रो-लेवल ट्रिगर: यह किसी पंक्ति परिवर्तन के किसी भी कॉलम मान से पूर्व या पश्चात में निष्पादित हो जाता हैI
 * 2) कॉलम-स्तरीय ट्रिगर: निर्दिष्ट कॉलम परिवर्तन से पूर्व या पश्चात में इसे निष्पादित किया जाता हैI
 * 3) प्रत्येक पंक्ति प्रकार के लिए: यह ट्रिगर सम्मिलित/अद्यतन/विस्थापित किये जाने से प्रभावित परिणाम दृढ़ की प्रत्येक पंक्ति के लिए निष्पादित हो जाता हैI
 * 4) प्रत्येक कथन प्रकार के लिए: यह ट्रिगर सम्पूर्ण परिणाम दृढ़ के लिए केवल निष्पादित होता है, किन्तु कथन के निष्पादित होने पर भी अग्नि प्रकट हो जाती है।

प्रणाली स्तरीय ट्रिगर्स
Oracle8i से, डेटाबेस प्रोग्राम- लॉगऑन, लॉगऑफ़, स्टार्टअप- आकाशवाणी ट्रिगर्स को सक्रिय कर सकते हैं।

माइक्रोसॉफ्ट एसक्यूएल सर्वर
डीडीएल ट्रिगर्स के लिए माइक्रोसॉफ्ट एसक्यूएल सर्वर में सभी उपलब्ध फायरिंग इवेंट्स की सूची माइक्रोसॉफ्ट एसक्यूएल पर उपलब्ध है।

अस्थायी सम्मिलित एवं विस्थापित किये गए सारणी तक पहुँचने के माध्यम से ट्रिगर्स (या संशोधन के पश्चात डेटा का परीक्षण) में नियमबद्ध क्रियाएं करना।

पोस्टग्रेएसक्यूएल
1997 में ट्रिगर्स के लिए समर्थन प्रस्तुत किया गया, एसक्यूएल: 2003 में निम्नलिखित कार्यक्षमता पूर्व पोस्टग्रेएसक्यूएल में प्रारम्भ नहीं की गई थी: सार: CREATE TRIGGER name { BEFORE | AFTER } { event [ OR ... ] }
 * एसक्यूएल ट्रिगर्स को विशिष्ट कॉलम के अद्यतन पर अग्नि प्रकट करने की अनुमति देता है; पोस्टग्रेएसक्यूएल के संस्करण 9.0 के रूप में यह सुविधा पोस्टग्रेएसक्यूएल में भी प्रारम्भ की गई है।
 * मानक सेलेक्ट (एसक्यूएल), इन्सर्ट (एसक्यूएल), अद्यतन (एसक्यूएल) के अतिरिक्त कई एसक्यूएल कथन के निष्पादन की अनुमति देता है, जैसे क्रिएट टेबल को ट्रिगर कार्य के रूप में, यह क्रिएट टेबल को संबोधन करने के लिए संग्रहीत कार्यविधि या कार्यक्रम बनाकर किया जा सकता है।

ON TABLE [ FOR [ EACH ] { ROW | STATEMENT } ] EXECUTE PROCEDURE funcname ( arguments )

फायरबर्ड
फ़ायरबर्ड (डेटाबेस सर्वर) प्रति टेबल ट्रिगर्स से पूर्व या पश्चात में, सम्मिलित करें (INSERT), अद्यतन करें (UPDATE), विस्थापित (DELETE) (या इसके किसी भी संयोजन) ट्रिगर्स के कई पंक्ति-स्तर का समर्थन करता है, जहां वे सदैव डिफ़ॉल्ट सारणी परिवर्तनों के अतिरिक्त होते हैं, एवं ट्रिगर का क्रम एक-दूसरे को निर्दिष्ट किया जा सकता है जहां यह अस्पष्ट होगा (POSITION क्लॉज।) ट्रिगर दृश्यों पर भी उपस्थित हो सकते हैं, जहां वे सदैव ट्रिगर के अतिरिक्त डिफ़ॉल्ट अद्यतन योग्य दृश्य तर्क को प्रतिस्थापित करते हैं। (संस्करण 2.1 से पूर्व, डिफ़ॉल्ट लॉजिक के साथ-साथ अपडेट किए जाने योग्य माने जाने वाले दृश्यों पर ट्रिगर चलेंगे।)

फायरबर्ड म्यूटेटिंग टेबल अपवाद (आकाशवाणी के जैसे) नहीं उठाता है, एवं ट्रिगर्स डिफ़ॉल्ट रूप से नेस्ट एवं रिकर्स दोनों की आवश्यकता होती है (एसक्यूएल सर्वर नेस्टिंग की अनुमति देता है, किन्तु डिफ़ॉल्ट रूप से रिकर्सन नहीं।) फायरबर्ड के ट्रिगर नए एवं प्राचीन संदर्भ परिचारक का उपयोग करते हैं (सम्मिलित एवं विस्थापित किये गए टेबल नहीं) एवं ट्रिगर के वर्तमान उपयोग को प्रदर्शित करने के लिए अपडेटिंग, इन्सर्टिंग एवं डिलीटिंग फ़्लैग प्रदान करते है। {CREATE | RECREATE | CREATE OR ALTER} TRIGGER name FOR {table name | view name}[ACTIVE | INACTIVE] {BEFORE | AFTER} {INSERT [OR UPDATE] [OR DELETE] | UPDATE [OR INSERT] [OR DELETE] | DELETE [OR UPDATE] [OR INSERT] } [POSITION n] AS BEGIN .... END संस्करण 2.1 के अनुसार, फायरबर्ड अतिरिक्त रूप से निम्नलिखित डेटाबेस-स्तरीय ट्रिगर्स का समर्थन करता है:


 * कनेक्ट करें (यहां उठाए गए अपवाद कनेक्शन को पूर्ण होने से बाधित करते है)
 * डिस्कनेक्ट करें
 * लेन-देन प्रारंभ
 * ट्रांज़ैक्शन कमिट (यहाँ उठाए गए अपवाद लेनदेन को कमिट करने से बाधित होता हैं, या दो-चरण की कमिटमेंट सम्मलित होने पर आयोजन करते हैं)
 * लेनदेन रोलबैक

डेटाबेस-स्तरीय ट्रिगर मल्टी-टेबल बाधाओं को आरम्भ करने में सहायता कर सकते हैं, या भौतिक विचारों का अनुकरण कर सकते हैं। यदि ट्रांज़ेक्शन कमिट ट्रिगर में अपवाद उठाया जाता है, तो ट्रिगर द्वारा अब तक किए गए परिवर्तन वापस ले लिए जाते हैं एवं क्लाइंट एप्लिकेशन को अधिसूचित किया जाता है, किन्तु आदान-प्रदान सक्रिय रहता है जैसे कि कमिट (COMMIT) का कभी अनुरोध नहीं किया गया था; क्लाइंट एप्लिकेशन परिवर्तन करना निरंतर रख सकता है एवं कमिट (COMMIT) का पुनः अनुरोध कर सकता है।

डेटाबेस ट्रिगर्स के लिए सिंटैक्स: {CREATE | RECREATE | CREATE OR ALTER} TRIGGER name[ACTIVE | INACTIVE] ON {CONNECT | DISCONNECT | TRANSACTION START | TRANSACTION COMMIT | TRANSACTION ROLLBACK} [POSITION n] AS BEGIN ..... END

माईएसक्यूएल/मारिया डीबी
माईएसक्यूएल/मारिया डीबी डीबीएमएस में ट्रिगर्स के लिए सीमित समर्थन माईएसक्यूएल (MySQL) के 5.0 संस्करण में सम्मिलित किया गया था, जिसे 2005 में प्रारम्भ किया गया था। संस्करण 8.0 के अनुसार, वे डीडीएल (DDL) (डेटा परिवर्तित भाषा) ट्रिगर्स एवं DML (डेटा मैनीपुलेशन भाषा) ट्रिगर्स के लिए अनुमति देते हैं। वे ट्रिगर्स को परिभाषित करने के लिए किसी भी प्रकार के डीडीएल ट्रिगर (पूर्व या पश्चात) का उपयोग करने की अनुमति देते हैं। वे क्लॉज क्रिएट ट्रिगर का उपयोग करके बनाए गए हैं एवं क्लॉज ड्रॉप ट्रिगर का उपयोग करके विस्थापित कर दिए गए हैं। किसी प्रोग्राम के घटित होने पर कहे जाने वाले कथन को प्रत्येक पंक्ति के लिए क्लॉज के पश्चात परिभाषित किया जाता है, उसके पश्चात कीवर्ड (निर्णीत या प्रारम्भ) होता है, जो प्रदर्शित करता है कि क्या क्रमशः अभिव्यक्ति या कथन है।

आईबीएम डीबी2 एलयूडब्ल्यू
एलयूडब्ल्यू (LUW) के लिए डीबी2 (DB2) के रूप में ज्ञात वितरित प्रणाली के लिए आईबीएम डीबी2 (एलयूडब्ल्यू का अर्थ है लिनक्स, यूनिक्स, विंडो) तीन ट्रिगर प्रकारों का समर्थन करता है: ट्रिगर से पूर्व, ट्रिगर के पश्चात एवं ट्रिगर के अतिरिक्त कथन स्तर एवं पंक्ति स्तर ट्रिगर दोनों समर्थित हैं। यदि टेबल पर चिकित्सा के लिए अधिक ट्रिगर हैं तो ट्रिगर निर्माण डेटा द्वारा फायरिंग आदेश निर्धारित किया जाता है। चूंकि संस्करण 9.7 आईबीएम डीबी2 स्वाधीनता आदान-प्रदान का समर्थन करता है। ट्रिगर से पूर्व डेटा का अन्वेषण करने एवं यह निश्चित करने के लिए है कि क्या चिकित्सा की अनुमति दी जानी चाहिए। यदि ट्रिगर से पूर्व निर्देश मुक्त किया जाता है तो चिकित्सा निरस्त कर दी जाती है एवं कोई डेटा परिवर्तित नहीं किया जाता है। डीबी2 में पूर्व ट्रिगर्स केवल पढ़ने के लिए होते हैं— आप पूर्व ट्रिगर्स में डेटा को संशोधित नहीं कर सकते हैं। ट्रिगर्स को पोस्ट प्रोसेसिंग के लिए डिज़ाइन किए जाने के पश्चात अनुरोध किए गए परिवर्तन के पश्चात किया गया था। ट्रिगर्स के पश्चात डेटा को टेबल में लिख सकते हैं एवं कुछ के विपरीत अन्य डेटाबेस आप किसी भी सारणी में लिख सकते हैं जिसमें सारणी सम्मिलित है जिस पर ट्रिगर संचालित होता है। ट्रिगर्स के अतिरिक्त विचारों को लिखने योग्य बनाने के लिए हैं।

ट्रिगर सामान्यतः एसक्यूएल पीएल भाषा में प्रोग्राम किए जाते हैं।

एसक्यूलाइट
CREATE [TEMP | TEMPORARY] TRIGGER [IF NOT EXISTS] [database_name .] trigger_name[BEFORE | AFTER | INSTEAD OF] {DELETE | INSERT | UPDATE [OF column_name [, column_name]...]} ON {table_name | view_name} [FOR EACH ROW] [WHEN condition is mandatory ] BEGIN ... END एसक्यूलाइट केवल पंक्ति-स्तरीय ट्रिगर्स का समर्थन करता है, कथन-लेवल ट्रिगर्स का समर्थन नहीं करता है।

अद्यतन करने योग्य दृश्य, जो एसक्यूलाइट में समर्थित को ट्रिगर्स के साथ अनुकरण किया जा सकता है।

एक्सएमएल डेटाबेस
अन्य-संबंधपरक डेटाबेस में ट्रिगर्स के कार्यान्वयन का उदाहरण सेडना (डेटाबेस) हो सकता है, जो एक्सक्वेरी (XQuery) पर आधारित ट्रिगर्स के लिए समर्थन प्रदान करता है। सेडना में ट्रिगर्स को एसक्यूएल: 2003 ट्रिगर्स के अनुरूप निर्मित किया गया था, किन्तु मूल रूप से एक्सएमएल क्वेरी एवं अद्यतन भाषा (एक्सपाथ, स्क्वेरी एवं एक्सएमएल अद्यतन भाषा) पर आधारित था।

सेडना में ट्रिगर डेटाबेस में संग्रहीत एक्सएमएल प्रपत्र के किसी भी नोड पर स्थित होता है। जब इन नोड्स को अद्यतन किया जाता है, तो ट्रिगर स्वचालित रूप से एक्सक्वेरी प्रश्नों एवं उसके शरीर में निर्दिष्ट अपडेट को निष्पादित करता है। उदाहरण के लिए, निम्न ट्रिगर व्यक्ति नोड विलोपन को निरस्त कर देता हैI CREATE TRIGGER "trigger3"

BEFORE DELETE ON doc("auction")/site//person FOR EACH NODE DO    { if (exists($WHERE//open_auction/bidder/personref/@person=$OLD/@id)) then else $OLD; }

पंक्ति एवं कथन स्तर ट्रिगर
यह ज्ञात करने के लिए कि ट्रिगर व्यवहार कैसे कार्य करता है, आपको दो मुख्य प्रकार के ट्रिगर्स के विषय में जानकारी प्राप्त होनी चाहिए, ये रो एवं कथन लेवल ट्रिगर हैं। दोनों के मध्य का अंतर यह है कि ट्रिगर के अंदर कोड को कितनी बार एवं किस समय निष्पादित किया जाता है।

मान लीजिए कि आपके पास ट्रिगर है जिसे किसी निश्चित सारणी में अद्यतन पर आह्वान करने के लिए बनाया गया है। अद्यतन से प्रभावित होने वाली प्रत्येक पंक्ति के लिए पंक्ति स्तर ट्रिगर निष्पादित होंगे। यह ध्यान रखना महत्वपूर्ण है कि यदि अद्यतन (UPDATE) कमांड से कोई पंक्ति प्रभावित नहीं होती है, तो ट्रिगर के अंदर किसी भी कोड को निष्पादित नहीं करेगा। अद्यतन से कितनी पंक्तियाँ प्रभावित हैं, इस पर ध्यान दिए बिना कथन लेवल ट्रिगर्स का आह्वान किया जाएगा। यहां यह ध्यान रखना महत्वपूर्ण है कि भले ही अद्यतन कमांड किसी भी पंक्ति को प्रभावित न करे, तथापि ट्रिगर के अंदर कोड को निष्पादित किया जाएगा।

पूर्व एवं पश्चात के विकल्पों का उपयोग करके निर्धारित करें कि ट्रिगर कब कहा जाता है। मान लीजिए कि आपके पास ट्रिगर है जिसे इन्सर्ट पर निश्चित सारणी में कहा जाता है। यदि आपका ट्रिगर पूर्व विकल्प का उपयोग कर रहा है, तो सारणी में इन्सर्ट होने से पूर्व ट्रिगर के अंदर कोड निष्पादित किया जाएगा। पूर्व ट्रिगर का सामान्य उपयोग इन्सर्ट के इनपुट मानों को सत्यापित करना है, या तदनुसार मानों को संशोधित करना है। अब मान लें कि हमारे पास ट्रिगर है जो इसके अतिरिक्त आफ्टर का उपयोग करता है। सारणी में इन्सर्ट होने के पश्चात ट्रिगर के अंदर कोड निष्पादित किया जाता है। इस ट्रिगर का उदाहरण उपयोग किए गए परिवर्तनों का ट्रैक रखते हुए, डेटाबेस में किसने प्रविष्टियां की हैं, इसकी प्रक्रिया इतिहास बना रही है। इन विकल्पों का उपयोग करते समय आपको कुछ कथनो का ध्यान रखना होगा। पूर्व विकल्प सारणी को संशोधित करने की अनुमति नहीं देता है, यही कारण है कि इनपुट सत्यापन व्यावहारिक उपयोग है। ट्रिगर्स के पश्चात का उपयोग करने से ऑडिट इतिहास सारणी में चिह्नित करने जैसी सारणी को संशोधित कर सकते हैं।

यह निर्धारित करने के लिए ट्रिगर बनाते समय कि क्या यह कथन या पंक्ति स्तर है, केवल पंक्ति स्तर के लिए प्रत्येक पंक्ति के लिए खंड सम्मिलित करें, या कथन स्तर के लिए खंड को त्याग दें। ट्रिगर के अतिरिक्त इन्सर्ट (एसक्यूएल)/अपडेट (एसक्यूएल)/विस्थापित (एसक्यूएल) कमांड का उपयोग करने से सावधान रहें, क्योंकि ट्रिगर रिकर्सन (कंप्यूटर विज्ञान) संभव है, जिससे अनुचित व्यवहार होता है। नीचे दिए गए उदाहरणों में प्रत्येक ट्रिगर भिन्न सारणी को संशोधित कर रहा है, जो संशोधित किया जा रहा है, उसे देखकर कुछ सामान्य अनुप्रयोगों को देख सकते हैं जब विभिन्न ट्रिगर प्रकारों का उपयोग किया जाता है।

निम्नलिखित पंक्ति स्तर ट्रिगर का ओरेकल (Oracle) सिंटैक्स उदाहरण है जिसे प्रभावित प्रत्येक पंक्ति के लिए अद्यतन के पश्चात कहा जाता है। इस ट्रिगर को फोन बुक डेटाबेस के अद्यतन पर आह्वान किया जाता है। जब ट्रिगर का आह्वान किया जाता है तो यह फोन_बुक_ऑडिट नाम की भिन्न सारणी में प्रविष्टि सम्मिलित करता है। स्कीमा ऑब्जेक्ट्स जैसे अनुक्रमों का लाभ उठाने में सक्षम होने वाले ट्रिगर्स पर भी ध्यान दें, इस उदाहरण में ऑडियो (audio)_आईडी (id)_ अनुक्रम नेक्सवैल (sequence.nexVal) का उपयोग फोन_बुक_ऑडिट सारणी में अद्वितीय प्राथमिक कुंजी उत्पन्न करने के लिए किया जाता है। CREATE OR REPLACE TRIGGER phone_book_audit

AFTER UPDATE ON phone_book FOR EACH ROW BEGIN INSERT INTO phone_book_audit (audit_id,audit_change, audit_l_name, audit_f_name, audit_old_phone_number, audit_new_phone_number, audit_date) VALUES (audit_id_sequence.nextVal,'Update', :OLD.last_name, :OLD.first_name, :OLD.phone_number, :NEW.phone_number, SYSDATE); END; अब अंतिम नाम 'जोन्स' वाले लोगों के लिए फोन_बुक टेबल पर अपडेट (एसक्यूएल) आह्वान करना।

UPDATE phone_book SET phone_number = '111-111-1111' WHERE last_name = 'Jones';

ध्यान दें कि फोन_नंबर_ऑडिट सारणी अब दो प्रविष्टियों से संपन्न है। यह डेटाबेस में 'जोन्स' के अंतिम नाम के साथ दो प्रविष्टियों के कारण है। चूंकि अपडेट दो भिन्न-भिन्न पंक्ति मानों को संशोधित करता है, इसलिए बनाए गए ट्रिगर का दो बार आह्वान किया गया था।

पश्चात-स्टेटमेंट-लेवल ट्रिगर
ओरेकल सिंटैक्स कथन ट्रिगर जिसे फोन_बुक सारणी में अद्यतन के पश्चात कहा जाता है। जब ट्रिगर का आह्वान किया जाता है तो यह फ़ोन _बुक _एडिट _इतिहास सारणी में सम्मिलित करता हैI CREATE OR REPLACE TRIGGER phone_book_history

AFTER UPDATE ON phone_book BEGIN INSERT INTO phone_book_edit_history (audit_history_id, username, modification, edit_date) VALUES (audit_history_id_sequence.nextVal, USER,'Update', SYSDATE); END; अब उपरोक्त उदाहरण के समान ही अपडेट कर रहे हैं, चूँकि इस बार कथन लेवल ट्रिगर के साथ होता है।

UPDATE phone_book SET phone_number = '111-111-1111' WHERE last_name = 'Jones';

परिणाम दर्शाता है कि ट्रिगर को केवल आह्वान किया गया था, तत्प्श्चात अपडेट ने दो पंक्तियों को परिवर्तित कर दिया है।

प्रत्येक से पूर्व - पंक्ति-स्तर ट्रिगर
यह उदाहरण प्रत्येक पंक्ति ट्रिगर से पूर्व प्रदर्शित करता है जो व्हेन (WHEN) वचन का उपयोग करके इन्सर्ट (INSERT) को संशोधित करता है। यदि अंतिम नाम सबस्ट्रेट (SUBSTR) प्रोग्राम का उपयोग करके 10 अक्षरों से बड़ा है हम अंतिम_नाम कॉलम मान को संक्षेप में परिवर्तित करते हैं। CREATE OR REPLACE TRIGGER phone_book_insert

BEFORE INSERT ON phone_book FOR EACH ROW WHEN (LENGTH(new.last_name) > 10) BEGIN :new.last_name := SUBSTR(:new.last_name,0,1); END; अब बड़े नाम वाले किसी व्यक्ति का इन्सर्ट (INSERT) कर रहे हैं। INSERT INTO phone_book VALUES

(6, 'VeryVeryLongLastName', 'Erin', 'Minneapolis', 'MN', '989 University Drive', '123-222-4456', 55408, TO_DATE('11/21/1991', 'MM/DD/YYYY')); ट्रिगर ने उपरोक्त परिणाम के अनुसार कार्य किया, इन्सर्ट के मान को निष्पादित करने से पूर्व संशोधित किया।

पूर्व -कथन-लेवल ट्रिगर
डेटाबेस प्रतिबंधों को प्रारम्भ करते समय पूर्व कथन ट्रिगर का उपयोग करना विशेष रूप से उपयोगी होता है। यह उदाहरण प्रदर्शित करता है कि सारणी फोन_बुक पर किसी उपयोगकर्ता नाम पर प्रतिबंध कैसे प्रारम्भ किया जाए।

CREATE OR REPLACE TRIGGER hauschbc

BEFORE INSERT ON SOMEUSER.phone_book BEGIN RAISE_APPLICATION_ERROR (         num => -20050,          msg => 'Error message goes here.'); END; अब, जब किसी इन्सर्ट का प्रयास करने के पश्चात किसी उपयोगकर्ता पर लॉग इन होता है तो यह त्रुटि संदेश दिखाई देगा:

SQL Error: ORA-20050: Error message goes here.

इस प्रकार की कस्टम त्रुटियां इस कथन पर प्रतिबंध लगाती हैं कि संख्या चर को किस रूप में परिभाषित किया जा सकता है। कई अन्य पूर्व-निर्धारित त्रुटियों के कारण यह चर -20000 से -20999 की सीमा में होना चाहिए।

बाहरी संबंध

 * Microsoft SQL Server DROP TRIGGER
 * MySQL Database triggers
 * MySQL DB Create Triggers
 * DB2 CREATE TRIGGER statement
 * Oracle CREATE TRIGGER
 * PostgreSQL CREATE TRIGGER
 * Oracle Mutating Table Problems with DELETE CASCADE
 * SQLite Query Language: CREATE TRIGGER
 * Oracle's Documentation on Triggers