Theory
आधी रात का ticket छेड़छाड़िया
कल्पना कीजिए एक system user रात 2 बजे TicketDesk में log in करता है। वे बिना कोई असल काम किए एक critical bug ticket को Open से Closed हाथ से update करते हैं, बस अपना performance score कृत्रिम रूप से बढ़ाने के लिए। team leader सुबह आकर एक टूटा system पाते हैं और उनके पास कोई record नहीं कि data किसने modify किया। हम database engine को कैसे मजबूर करें कि अपने-आप ख़राब updates पकड़े, दोषी को खोजे, और इंसानी ईमानदारी पर निर्भर हुए बिना एक अपरिवर्तनीय audit log लिखे?
Theory
Motion-Activated Security Camera
अगर आप एक jewelry showroom की रक्षा करना चाहते हैं, आप एक ऐसा guard नहीं रखते जो बैठकर इंतज़ार करे कि एक चोर घुसने पर आप उसे बुलाएँ। इसके बजाय, आप एक motion-activated security camera लगाते हैं। camera पूरी तरह सुप्त रहता है जब तक कोई sensor path पार न करे। जिस पल हरकत होती है, यह तुरंत सक्रिय होता है और एक snapshot लेता है। एक database trigger वह बिल्कुल security camera है: यह आपकी tables के अंदर चुपचाप बैठता है और जिस क्षण एक data परिवर्तन होता है अपने-आप दागता है।
Theory
Database Triggers को परिभाषित करना
Oracle database dialect में, एक database trigger एक नामित, stored PL/SQL block है जो एक ख़ास table event की सीधी प्रतिक्रिया में अपने-आप execute होता, या दागता, है। ये events INSERT, UPDATE, या DELETE जैसी Data Manipulation Language (DML) actions से बने होते हैं। Triggers stored procedures से पूरी तरह अलग हैं क्योंकि वे user applications द्वारा हाथ से invoke या execute नहीं किए जा सकते। इसके बजाय, Oracle database engine उन्हें पारदर्शी रूप से चलाता है जब भी table modifications होते हैं।
At a glance
अलग table events के दौरान :OLD और :NEW qualifiers की उपलब्धता
| DML Operation | Old Values (:OLD) | New Values (:NEW) |
|---|---|---|
| INSERT | पूरी तरह NULL क्योंकि कोई पिछला record मौजूद नहीं | नए आ रहे data fields रखता है |
| UPDATE | data fields रखता है जैसे वे query से पहले मौजूद थे | प्रस्तावित replacement data fields रखता है |
| DELETE | data fields रखता है जैसे वे हटाने से पहले मौजूद थे | पूरी तरह NULL क्योंकि record अब मौजूद नहीं |
Practical
एक Ticket Audit Log Trigger बनाना
-- Enable terminal output
SET SERVEROUTPUT ON;
-- Create trigger to automatically track status modifications
CREATE OR REPLACE TRIGGER trg_audit_ticket_status
BEFORE UPDATE OF status ON tickets
FOR EACH ROW
BEGIN
-- Insert old and new values into a history table
INSERT INTO ticket_logs (ticket_id, old_status, new_status, changed_on)
VALUES (:OLD.id, :OLD.status, :NEW.status, SYSDATE);
END;
/Theory
Audit Trigger Syntax का विश्लेषण
आइए execution यांत्रिकी की जाँच करें। निर्देश BEFORE UPDATE OF status ON tickets Oracle को हमारा custom logic update statement स्थायी रूप से save होने से ठीक पहले execute करने का निर्देश देता है। FOR EACH ROW qualifier ज़रूरी है: यह एक row-level trigger निर्दिष्ट करता है, हमें query द्वारा modify किए हर अलग record की जाँच करने देते हुए। block body के अंदर, हम historical values पढ़ने के लिए :OLD keyword और आ रहे data fields को table को overwrite करने से पहले जाँचने के लिए :NEW keyword इस्तेमाल करते हैं।
Quiz
अगर एक row-level trigger रखती एक table के अंदर एक INSERT statement चलता है, pseudo-record attribute :OLD.title में कौन सा data होगा?
- पहले जोड़ी गई अंतिम row का title string
- यह NULL evaluate होगा
- Oracle द्वारा उत्पन्न एक default string value
- compiler विफल होगा और एक syntax error उठाएगा
Show the answer
यह NULL evaluate होगा
एक INSERT operation के दौरान, एक ताज़ा record पेश किया जा रहा है जहाँ पहले कोई historical row मौजूद नहीं थी। क्योंकि point करने को कोई old data नहीं है, :OLD pseudo-record के भीतर सारे attributes बिना कोई error फेंके अपने-आप NULL evaluate होते हैं।
Watch out
गुमशुदा FOR EACH ROW जाल
laboratory practical exams में भारतीय BCA students द्वारा की गई सबसे बार-बार होने वाली error FOR EACH ROW वाक्यांश छोड़ना है। इस ख़ास clause बिना, Oracle एक statement-level trigger बनाता है। Statement-level triggers प्रति query बिल्कुल एक बार execute होते हैं, चाहे आप 1 row modify करें या 1000 rows। अगर आप एक statement-level trigger के अंदर :NEW या :OLD जैसे row-specific qualifiers reference करने की कोशिश करते हैं, Oracle compiler तुरंत crash होगा और एक compilation error फेंकेगा।
Think first
Data को रोकना और बदलना
कल्पना कीजिए एक user lowercase अक्षरों में type किए priority के साथ एक ticket submit करता है। अगर हम चाहते हैं हमारा trigger record को रोके और save होने से पहले अपने-आप value को uppercase पर मजबूर करे, हमें एक BEFORE trigger इस्तेमाल करना चाहिए या एक AFTER trigger? tap करने से पहले जवाब मन में निकालिए।
Show the answer
आपको एक BEFORE trigger इस्तेमाल करना होगा! एक BEFORE row-level trigger आपको :NEW.priority := UPPER(:NEW.priority); जैसे assignment statements इस्तेमाल करके आ रहे records सीधे modify करने की अनोखी क्षमता देता है। अगर आप एक AFTER trigger के अंदर एक :NEW attribute बदलने की कोशिश करते हैं, Oracle एक गंभीर execution error फेंकेगा क्योंकि data पहले से अंतिम रूप दिया और storage block में commit किया जा चुका है।
Theory
Enterprise Compliance और अगले Semester का Mobile Data
production banking infrastructures में, backend engineers audit compliance लागू करने और financial fraud पारदर्शी रूप से पकड़ने के लिए database triggers पर निर्भर करते हैं। आप इस event-driven architecture से फिर अगले semester अपने Sem 3 BCA303 SQLite mobile development course में मिलेंगे। Triggers आपकी smartphone applications को जिस पल एक user एक update करता है तुरंत background tasks चलाने और offline local data records synchronize करने देंगे।
Summary
Key takeaways
- Triggers विशेष नामित PL/SQL blocks हैं जो database events द्वारा अपने-आप execute होते हैं।
- stored procedures के उलट, triggers external applications द्वारा हाथ से invoke या call नहीं किए जा सकते।
- BEFORE triggers disk commit से पहले आ रहे records का सत्यापन और modification देते हैं।
- AFTER triggers सहायक tracking tables में audit data logging के लिए इष्टतम हैं।
- FOR EACH ROW modifier एक statement trigger को एक row-level handler में बदल देता है।
- Row-level triggers :OLD और :NEW data qualifiers तक अनन्य पहुँच पाते हैं।
- Memory hook: Procedures पसंद से चलते हैं, पर triggers actions से दागते हैं!