4.4.12 · Coding › Databases
Ek database sirf ek passive box nahi hai jo rows rakhta hai — yeh code run kar sakta hai. Apni app mein raw data kheenchne ke bajay, wahan logic karne ke bajay, aur use wapas push karne ke bajay (3 network trips, baar baar), aap logic ko database ke andar store kar sakte hain, data ke paas hi . "Code in the DB" ke teen flavors hain:
Stored procedure = ek named program jo aap demand par call karte ho (CALL doThing()).
Function = ek named program jo ek value return karta hai aur SQL expressions ke andar use hone ke liye bana hai (SELECT tax(price)).
Trigger = ek program jo automatically fire hota hai jab data change hota hai (INSERT/UPDATE/DELETE).
WHY yeh matter karta hai: kam network chatter, centralized business rules, atomicity, aur DB aise invariants enforce kar sakta hai jo koi bhi application bypass nahi kar sakti.
Definition Stored procedure
Ek stored procedure ek precompiled, named block of procedural SQL hai jo database mein store hota hai, aur CALL ke saath explicitly invoke hota hai. Yeh IN, OUT, aur INOUT parameters le sakta hai, control flow (loops, conditionals) contain kar sakta hai, multiple statements run kar sakta hai, aur transactions manage kar sakta hai — lekin iska ek value return karna zaroori nahi hai.
WHY yeh exist karte hain?
Paisa transfer karne ki imagine karo: tumhe (1) account A se subtract karna hai, (2) account B mein add karna hai. Agar tumhari app yeh do alag queries mein karti hai aur beech mein crash ho jaaye, toh paisa gayab ho jaata hai. Ek stored procedure dono ko ek server-side call mein wrap karta hai taaki logic — aur uska transaction — ek trusted jagah mein rahe.
HOW yeh dikhta hai (MySQL syntax):
DELIMITER //
CREATE PROCEDURE transfer ( IN src INT , IN dst INT , IN amt DECIMAL ( 10 , 2 ))
BEGIN
START TRANSACTION ;
UPDATE accounts SET balance = balance - amt WHERE id = src;
UPDATE accounts SET balance = balance + amt WHERE id = dst;
COMMIT ;
END //
DELIMITER //
-- call it:
CALL transfer ( 1 , 2 , 100 . 00 );
Worked example Har step kyun?
DELIMITER // → Kyun? Procedure body mein ; hai. Hum statement terminator ko temporarily change karte hain taaki DB yeh na soche ki procedure pehle inner ; par khatam ho gayi.
IN src INT → Kyun? IN matlab "value jo procedure mein pass ki gayi, andar read-only." Isse caller source account hand over karta hai.
START TRANSACTION ... COMMIT → Kyun? Taaki ya toh dono updates hoon ya koi bhi na ho — atomicity server-side rehti hai, fragile app code mein nahi.
Ek function ek named routine hai jo exactly ek value return karni hi padti hai (RETURNS type) aur directly SQL expressions jaise SELECT, WHERE, ya ORDER BY ke andar embed ki ja sakti hai. Yeh typically deterministic aur side-effect-free (read-only) hone ke liye bani hoti hai.
WHY procedures se alag? Kyunki query planner ko ise query ke andar har row ke liye call karna hota hai. SELECT discount(price) FROM items ka koi matlab nahi hota agar discount koi COMMIT transaction kar sake ya kuch return na kare.
DELIMITER //
CREATE FUNCTION net_price (price DECIMAL ( 10 , 2 ), rate DECIMAL ( 4 , 3 ))
RETURNS DECIMAL ( 10 , 2 )
DETERMINISTIC
BEGIN
RETURN price * ( 1 + rate);
END //
DELIMITER //
-- use inside a query:
SELECT name , net_price(price, 0 . 18 ) AS with_tax FROM products;
Worked example Har step kyun?
RETURNS DECIMAL(10,2) → Kyun? Engine ko output type jaanna chahiye taaki woh ise expression mein plug kar sake.
DETERMINISTIC → Kyun? Optimizer ko bata hai "same inputs → same output," toh woh cache/optimize kar sakta hai aur ise indexes mein safely use kar sakta hai. Yahan jhooth bolna results corrupt kar deta hai.
RETURN ... → Kyun? Bina RETURN path ke function illegal hai — usse hamesha ek value yield karni hi hogi.
Stored Procedure
Function
Invoke hota hai
CALL (explicitly)
SQL expressions ke andar
Return karta hai
optional (OUT params)
exactly ek value
Data modify kar sakta hai
haan
usually nahi / restricted
Transactions
haan
typically nahi
SELECT mein use
nahi
haan
Ek trigger procedural code hai jise database automatically execute karta hai — table par kisi data-modifying event — INSERT, UPDATE, ya DELETE — ke response mein, ek specified ==timing (BEFORE ya AFTER)== par. Ise manually call nahi kiya ja sakta.
WHY triggers? Rules enforce karne ke liye chahe table ko koi bhi ya kuch bhi touch kare — even ek careless admin jo raw SQL run kar raha ho. Common uses: audit logs, derived columns auto-maintain karna, validation, cascading updates.
Magic pseudo-tables: OLD aur NEW
NEW.col → incoming value (INSERT aur UPDATE mein available).
OLD.col → previous value (UPDATE aur DELETE mein available).
DELIMITER //
CREATE TRIGGER audit_salary
AFTER UPDATE ON employees
FOR EACH ROW
BEGIN
IF NEW . salary <> OLD . salary THEN
INSERT INTO salary_log(emp_id, old_sal, new_sal, changed_at)
VALUES ( OLD . id , OLD . salary , NEW . salary , NOW ());
END IF ;
END //
DELIMITER //
Worked example Har step kyun?
AFTER UPDATE → AFTER kyun? Hum change tab log karna chahte hain jab woh row mein successfully commit ho chuka ho; BEFORE hume value ko likhne se pehle modify karne deta.
FOR EACH ROW → Kyun? Har affected row ke liye ek baar fire hota hai, per statement ek baar nahi. 50 rows ko hit karne wala UPDATE 50 entries log karta hai.
IF NEW.salary <> OLD.salary → Kyun? Noise se bachne ke liye — jab salary actually change nahi hui toh logging skip karo.
Intuition BEFORE vs AFTER — ka rule
BEFORE use karo incoming row ko validate ya alter karne ke liye (aap NEW.col ko assign kar sakte ho).
AFTER use karo change final hone ke baad react karne ke liye (logging, doosri tables mein cascading). AFTER trigger mein aap NEW ko assign nahi kar sakte — woh already likh chuka hai.
Common mistake "Functions aur procedures basically same hain, jo bhi chahein call karo."
Kyun sahi lagta hai: Dono named blocks of SQL hain parameters aur body ke saath — syntax almost identical hai. Fix: Ek function ek value return karta hai aur query ke andar callable hai ; ek procedure standalone call hota hai aur side effects/transactions le sakta hai . SELECT myprocedure() try karo → error. CALL myfunction() try karo → error. Invocation context dividing line hai.
Common mistake "Main apna function DETERMINISTIC mark kar dunga taaki faster chale."
Kyun sahi lagta hai: Yeh performance hint hai, toh jyada = better. Fix: DETERMINISTIC ek promise hai, tuning knob nahi. Agar tumhara function NOW() ya koi table read karta hai aur tum jhooth bolte ho ki yeh deterministic hai, toh optimizer ek stale result cache kar sakta hai → silently galat data. Ise tabhi declare karo jab output truly sirf inputs par depend kare.
Common mistake "DELETE trigger mein main bas NEW use karunga dekhne ke liye kya delete hua."
Kyun sahi lagta hai: NEW "involved row" jaisa lagta hai. Fix: DELETE par koi new row nahi hoti — sirf OLD exist karta hai. Pure INSERT par sirf NEW exist karta hai. Mnemonic: DELETE OLD ko rakhta hai, INSERT NEW laata hai, UPDATE mein dono hain.
Common mistake "Triggers free magic hain — apna sara logic wahan daal do."
Kyun sahi lagta hai: Automation clean lagta hai. Fix: Triggers hidden control flow hain — yeh invisibly fire hote hain, doosre triggers mein chain ho sakte hain (cascades), performance hurt karte hain, aur debug karne mein mushkil hain. Inhe overuse karne se "spooky action at a distance" banta hai. Inhe invariants ke liye use karo, general logic ke liye nahi.
Recall Feynman: ek 12-saal ke bachche ko explain karo
Database ko ek toy box socho. Normally tum andar jaate ho aur toys rearrange karte ho.
Ek stored procedure "Tidy Up" label wale button ki tarah hai — tum ise press karte ho aur yeh tumhare liye bahut saare steps karta hai.
Ek function box ke andar ek chhote calculator ki tarah hai — tum ise numbers dete ho aur yeh ek answer wapas deta hai , taaki tum ise doosri math karte waqt use kar sako.
Ek trigger ek magic sensor ki tarah hai: jab bhi tum koi toy add ya remove karte ho, yeh automatically ek diary mein note likhta hai — tumne isse kaha nahi, yeh bas hamesha karta hai.
Mnemonic Teeno yaad rakhne ka tarika
"PROCedure ko tum PROD karte ho (call karte ho), FUNCtion ek FUN value wapas deta hai, TRIGger khud ko kheeenchta hai."
Aur trigger rows ke liye: OLD–DELETE, NEW–INSERT, UPDATE = DONO.
Answers cover karo aur recall karo: OLD kab use kar sakte ho? NEW kab? Function ko RETURNS kyun chahiye? Procedure ko DELIMITER kyun chahiye?
Transactions and ACID — procedures multi-statement atomic units wrap karte hain.
SQL Queries (SELECT, JOIN) — functions in expressions mein plug hote hain.
Database Normalization — triggers derived/denormalized columns maintain kar sakte hain.
Indexes — deterministic functions functional indexes power kar sakte hain.
Concurrency Control — triggers aur procedures locks ke under run karte hain.
Stored procedure ko kaun invoke karta hai? Ek explicit CALL procName(args) statement.
Function ko hamesha kya karna padta hai jo procedure ko nahi karna? Exactly ek value return karna (RETURNS type + RETURN).
Kya stored procedure ko SELECT clause ke andar use kar sakte hain? Nahi — sirf functions ko SQL expressions mein embed kiya ja sakta hai.
Trigger ki do timings kya hain? BEFORE aur AFTER data event ke.
Kin trigger events mein OLD available hota hai? UPDATE aur DELETE mein (previous row values).
Kin trigger events mein NEW available hota hai? INSERT aur UPDATE mein (incoming row values).
Trigger mein AFTER ki jagah BEFORE kyun use karein? Incoming NEW row ko likhne se pehle validate ya modify karne ke liye.
FOR EACH ROW ka matlab kya hai?Trigger per statement ek baar ki jagah har affected row ke liye ek baar fire hota hai.
DELIMITER // procedure definitions ke aas paas kyun aata hai?Statement terminator change karne ke liye taaki inner ; procedure ka end na samjha jaaye.
Function ko DETERMINISTIC declare karna kya promise karta hai? Same inputs hamesha same output denge (koi hidden state / side effects nahi).
INOUT parameter kya karta hai?Caller ko ek value pass-in karta hai aur ek (possibly modified) value wapas return karta hai.
Money transfer ke liye app-side logic se zyada stored procedure kyun prefer karein? Yeh dono updates ko ek server-side atomic transaction mein wrap karta hai, taaki crash half-done transfer nahi chhhod sakta.
Kya DELETE trigger NEW reference kar sakta hai? Nahi — DELETE mein koi new row nahi hoti; sirf OLD exist karta hai.
Used inside SQL expressions