Theory
મધરાતનો Ticket સાથે ચેડાં કરનાર
કલ્પો કે એક system નો user રાત્રે 2 વાગ્યે TicketDesk માં log in કરે છે. એ કોઈ ખરેખરું કામ કર્યા વગર, ખાલી પોતાનો દેખાવનો score કૃત્રિમ રીતે વધારવા, એક નિર્ણાયક bug ના ticket ને હાથે Open થી Closed કરી નાખે છે. Team leader સવારે આવીને એક તૂટેલી system શોધે છે અને એમની પાસે કોઈ નોંધ નથી કે data કોણે બદલ્યો. તો આપણે database engine ને માણસની પ્રામાણિકતા પર આધાર રાખ્યા વગર આપોઆપ ખરાબ updates પકડવા, ગુનેગારને શોધવા, અને એક ન બદલી શકાય એવો audit log લખવા કેવી રીતે મજબૂર કરીએ?
Theory
હલનચલનથી ચાલુ થતો Security Camera
જો તમારે એક ઝવેરાતના showroom ને બચાવવો હોય, તમે એવો ચોકીદાર રાખતા નથી જે ચોર ઘૂસે ત્યારે તમે એને બોલાવો એની રાહ જોઈને બેસી રહે. એને બદલે, તમે હલનચલનથી ચાલુ થતો એક security camera બેસાડો છો. કોઈ sensor ના રસ્તે ન આવે ત્યાં સુધી camera સંપૂર્ણપણે સૂતો રહે છે. જે ક્ષણે હલનચલન થાય, એ તરત સક્રિય થાય છે અને એક તસવીર લે છે. એક database trigger બિલકુલ એ જ security camera છે: એ તમારાં tables ની અંદર ચૂપચાપ બેસે છે અને data નો ફેરફાર થાય એ જ ક્ષણે આપોઆપ સળગે છે.
Theory
Database Triggers ની વ્યાખ્યા
Oracle database ના dialect માં, એક database trigger એ નામવાળો, સંઘરાયેલો PL/SQL block છે જે એક ચોક્કસ table ની ઘટનાના સીધા પ્રતિભાવમાં આપોઆપ ચાલે છે, કે સળગે છે. આ ઘટનાઓ INSERT, UPDATE, કે DELETE જેવી Data Manipulation Language (DML) ક્રિયાઓની બનેલી છે. Triggers stored procedures થી સંપૂર્ણપણે અલગ છે કારણ કે એમને user ની applications દ્વારા હાથે બોલાવી કે ચલાવી શકાતા નથી. એને બદલે, જ્યારે પણ table માં ફેરફારો થાય ત્યારે Oracle database engine એમને પારદર્શક રીતે ચલાવે છે.
At a glance
જુદી table ની ઘટનાઓ દરમિયાન :OLD અને :NEW qualifiers ની ઉપલબ્ધતા
| DML કામગીરી | જૂની Values (:OLD) | નવી Values (:NEW) |
|---|---|---|
| INSERT | સંપૂર્ણપણે NULL કારણ કે કોઈ આગળનો record અસ્તિત્વમાં નથી | નવા આવતા data નાં fields ધરાવે છે |
| UPDATE | Query પહેલાં જેવાં હતાં એવાં data નાં fields ધરાવે છે | સૂચિત બદલી નાખતાં data નાં fields ધરાવે છે |
| DELETE | કાઢી નાખતાં પહેલાં જેવાં હતાં એવાં data નાં fields ધરાવે છે | સંપૂર્ણપણે NULL કારણ કે record હવે અસ્તિત્વમાં નથી |
Practical
Building a 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 ને કહે છે કે update નું statement કાયમ માટે સચવાય એની બરાબર પહેલાં આપણી custom logic ચલાવે. FOR EACH ROW qualifier આવશ્યક છે: એ એક row-level trigger નિર્દિષ્ટ કરે છે, જે આપણને query દ્વારા બદલાયેલો દરેક અલગ record તપાસવા દે છે. Block ના શરીરની અંદર, આપણે ઐતિહાસિક values વાંચવા :OLD keyword અને આવતાં data નાં fields એ table ને ફરીથી લખે એ પહેલાં એમને તપાસવા :NEW keyword વાપરીએ છીએ.
Quiz
જો એક row-level trigger ધરાવતા table ની અંદર એક INSERT statement ચાલે, તો pseudo-record નું attribute :OLD.title કયો data ધરાવશે?
- પહેલાં ઉમેરાયેલી છેલ્લી હરોળની title ની string
- એ NULL આંકાશે
- Oracle દ્વારા બનાવાયેલી એક default string ની value
- Compiler નિષ્ફળ જશે અને એક syntax error ઊભી કરશે
Show the answer
એ NULL આંકાશે
એક INSERT ની કામગીરી દરમિયાન, એક તાજો record રજૂ થઈ રહ્યો છે જ્યાં પહેલાં કોઈ ઐતિહાસિક હરોળ અસ્તિત્વમાં નહોતી. કારણ કે ઈશારો કરવા માટે કોઈ જૂનો data નથી, :OLD pseudo-record ની અંદરનાં બધાં attributes કોઈ error ફેંક્યા વગર આપોઆપ NULL આંકાય છે.
Watch out
ખૂટતા FOR EACH ROW નો ફાંદો
Laboratory ની practical પરીક્ષાઓમાં ભારતીય BCA students સૌથી વારંવાર જે ભૂલ કરે છે એ છે FOR EACH ROW વાક્યાંશ છોડી દેવો. આ ચોક્કસ clause વગર, Oracle એક statement-level trigger બનાવે છે. Statement-level triggers query દીઠ બિલકુલ એક વાર ચાલે છે, ભલે તમે 1 હરોળ બદલો કે 1000 rows. જો તમે એક statement-level trigger ની અંદર :NEW કે :OLD જેવા હરોળ-ચોક્કસ qualifiers નો સંદર્ભ લેવાનો પ્રયાસ કરો, Oracle compiler તરત crash થશે અને એક compilation ની error ફેંકશે.
Think first
Data ને આંતરવો અને બદલવો
કલ્પો કે એક user નાના અક્ષરોમાં ટાઈપ કરેલી priority સાથે એક ticket રજૂ કરે છે. જો આપણે ઇચ્છીએ કે આપણો trigger record ને આંતરે અને એ સચવાય એ પહેલાં value ને આપોઆપ મોટા અક્ષરોમાં ફેરવે, તો આપણે એક BEFORE trigger વાપરવો જોઈએ કે એક AFTER trigger? Tap કરતાં પહેલાં મનમાં જવાબ કાઢો.
Show the answer
તમારે એક BEFORE trigger વાપરવો જ પડશે! એક BEFORE row-level trigger તમને :NEW.priority := UPPER(:NEW.priority); જેવાં assignment statements વાપરીને આવતા records સીધા બદલવાની અનન્ય ક્ષમતા આપે છે. જો તમે એક AFTER trigger ની અંદર એક :NEW attribute બદલવાનો પ્રયાસ કરો, Oracle એક ગંભીર execution ની error ફેંકશે કારણ કે data પહેલેથી આખરી થઈને સંગ્રહના block માં commit થઈ ગયો છે.
Theory
Enterprise Compliance અને આગલા Semester નો Mobile Data
Production ના banking ના માળખાંમાં, backend engineers audit ના પાલનનો અમલ કરવા અને નાણાકીય છેતરપિંડી પારદર્શક રીતે પકડવા database triggers પર આધાર રાખે છે. તમે આગલા semester માં તમારા Sem 3 BCA303 ના SQLite mobile development ના course માં આ ઘટના-આધારિત માળખું ફરી મળશો. Triggers તમારી smartphone ની applications ને user એક update કરે એ જ ક્ષણે તરત પડદા પાછળનાં કામ ચલાવવા અને offline સ્થાનિક data ના records સુમેળમાં લાવવા દેશે.
Summary
Key takeaways
- Triggers એ ખાસ નામવાળા PL/SQL blocks છે જે database ની ઘટનાઓ દ્વારા આપોઆપ ચાલે છે.
- Stored procedures થી વિપરીત, triggers ને બહારની applications દ્વારા હાથે બોલાવી કે ચલાવી શકાતા નથી.
- BEFORE triggers disk પર commit થતાં પહેલાં આવતા records ની ચકાસણી અને ફેરફાર કરવા દે છે.
- AFTER triggers સહાયક tracking tables માં audit નો data નોંધવા શ્રેષ્ઠ છે.
- FOR EACH ROW modifier એક statement trigger ને એક row-level handler માં ફેરવે છે.
- Row-level triggers ને :OLD અને :NEW data ના qualifiers સુધી અનન્ય પ્રવેશ મળે છે.
- Memory hook: Procedures પસંદગીથી ચાલે છે, પણ triggers ક્રિયાઓથી સળગે છે!