Free tutorials & notes in Hindi & English · Clean code examples · Mobile friendly learning
MySQL + SQL · Lesson 96

MySQL Stored Procedures

Stored Procedure क्या है?

Stored procedure named SQL routine है जो MySQL में stored और CALL से invoke होती है। यह compound BEGIN ... END, parameters, local variables, conditions, loops, handlers, multiple statements, result sets और data changes use कर सकती है।

FeatureProcedureFunction
InvocationCALL name(...)Expression में
ParametersIN, OUT, INOUTInput only
ResultSets, OUT, data effectsOne RETURN value
UseWorkflow/database operationScalar computation
Design rule: Procedure SQL execution centralize करती है, automatically good architecture नहीं। Contracts narrow, permissions explicit और definitions version-controlled रखें।

Verified Orders Lab

DROP TABLE IF EXISTS orders_proc_lab;
CREATE TABLE orders_proc_lab (
  order_id INT AUTO_INCREMENT PRIMARY KEY,
  customer_id INT NOT NULL,
  status VARCHAR(20) NOT NULL DEFAULT 'PENDING',
  order_date DATE NOT NULL,
  total_amount DECIMAL(10,2) NOT NULL,
  approved_by VARCHAR(50)
) ENGINE = InnoDB;

INSERT INTO orders_proc_lab
(order_id, customer_id, status, order_date, total_amount, approved_by)
VALUES
(1,101,'PAID','2026-08-01',1200,'Admin'),
(2,101,'PENDING','2026-08-05',500,NULL),
(3,102,'PAID','2026-08-03',750,'Admin'),
(4,103,'CANCELLED','2026-08-04',300,NULL),
(5,101,'PAID','2026-08-10',1500,'Manager'),
(6,102,'PENDING','2026-08-11',900,NULL),
(7,104,'PAID','2026-08-12',2200,'Manager'),
(8,101,'PAID','2026-08-14',650,'Admin');

Lab read summaries और controlled status changes support करती है। Routine creation appropriate privileges वाले account से चलाएँ।

Procedure Create और CALL

DELIMITER //
CREATE PROCEDURE list_customer_orders(
  IN p_customer_id INT
)
READS SQL DATA
BEGIN
  SELECT order_id, status, order_date, total_amount
  FROM orders_proc_lab
  WHERE customer_id = p_customer_id
  ORDER BY order_date, order_id;
END //
DELIMITER ;

CALL list_customer_orders(101);
1 | PAID | 2026-08-01 | 1200.00 2 | PENDING | 2026-08-05 | 500.00 5 | PAID | 2026-08-10 | 1500.00 8 | PAID | 2026-08-14 | 650.00

DELIMITER mysql command-line client command है, server stored SQL नहीं। यह internal semicolons को one CREATE statement का part pass कराता है। GUI/drivers का workflow अलग हो सकता है।

IN, OUT और INOUT Parameters

ModeDirectionBehavior
INCaller to routineDefault; changes return नहीं
OUTRoutine to callerInside NULL; user variable pass
INOUTBothInitial value change होकर return
DELIMITER //
CREATE PROCEDURE customer_paid_summary(
  IN  p_customer_id INT,
  OUT p_paid_count INT,
  OUT p_paid_total DECIMAL(12,2)
)
READS SQL DATA
BEGIN
  SELECT COUNT(*), COALESCE(SUM(total_amount), 0)
  INTO p_paid_count, p_paid_total
  FROM orders_proc_lab
  WHERE customer_id = p_customer_id
    AND status = 'PAID';
END //
DELIMITER ;

CALL customer_paid_summary(101, @paid_count, @paid_total);
SELECT @paid_count, @paid_total;
3 | 3350.00

INOUT supplied value normalize/accumulate कर सकता है, पर confusing contract hide न करें। Clear result set या documented output object app code के लिए easier हो सकता है।

Local Variables, IF और Validation

DELIMITER //
CREATE PROCEDURE approve_order(
  IN p_order_id INT,
  IN p_approved_by VARCHAR(50)
)
MODIFIES SQL DATA
BEGIN
  DECLARE v_status VARCHAR(20) DEFAULT NULL;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_status = NULL;

  IF p_approved_by IS NULL OR TRIM(p_approved_by) = '' THEN
    SIGNAL SQLSTATE '45000'
      SET MESSAGE_TEXT = 'Approver name is required';
  END IF;

  SELECT status INTO v_status
  FROM orders_proc_lab
  WHERE order_id = p_order_id;

  IF v_status IS NULL THEN
    SIGNAL SQLSTATE '45000'
      SET MESSAGE_TEXT = 'Order not found';
  ELSEIF v_status = 'CANCELLED' THEN
    SIGNAL SQLSTATE '45000'
      SET MESSAGE_TEXT = 'Cancelled order cannot be approved';
  ELSE
    UPDATE orders_proc_lab
    SET status='PAID', approved_by=p_approved_by
    WHERE order_id=p_order_id;
  END IF;
END //
DELIMITER ;

DECLARE block start में executable statements से पहले आता है। Parameters p_ और locals v_ रखें ताकि columns से ambiguity न हो।

CALL approve_order(6, 'Principal');
6 | PAID | Principal

Transactions, Handlers और Errors

Procedure automatically isolated transaction नहीं बनाती। Autocommit/session rules apply होते हैं। Routine transaction statements रख सकती है जहाँ permitted हों, पर context caller की same session का है।

DELIMITER //
CREATE PROCEDURE safe_mark_paid(
  IN p_order_id INT, IN p_user VARCHAR(50)
)
MODIFIES SQL DATA
BEGIN
  DECLARE EXIT HANDLER FOR SQLEXCEPTION
  BEGIN
    ROLLBACK;
    RESIGNAL;
  END;

  START TRANSACTION;
  UPDATE orders_proc_lab
  SET status='PAID', approved_by=p_user
  WHERE order_id=p_order_id AND status='PENDING';

  IF ROW_COUNT() <> 1 THEN
    SIGNAL SQLSTATE '45000'
      SET MESSAGE_TEXT='Pending order not found';
  END IF;
  COMMIT;
END //
DELIMITER ;
Architecture: Commit/rollback करने वाली procedure caller की session transaction control करती है। Large apps में transaction ownership one documented outer boundary पर better है।

Handler cleanup करे और RESIGNAL से failure client तक जाए। Errors swallow न करें।

Privileges, DEFINER और SQL SECURITY

  • Create के लिए CREATE ROUTINE
  • Invoke के लिए EXECUTE
  • SQL SECURITY DEFINER default; internal statements definer privileges से।
  • INVOKER caller privileges से।
  • Definer controlled durable account हो।
CREATE DEFINER = 'app_routine'@'localhost'
PROCEDURE report_orders(IN p_customer_id INT)
SQL SECURITY DEFINER
READS SQL DATA
SELECT order_id, status, total_amount
FROM orders_proc_lab
WHERE customer_id = p_customer_id;

DEFINER routine direct table grant के बिना constrained operation expose कर सकती है, पर dynamic SQL, broad parameters या weak validation boundary तोड़ सकती हैं। Least privilege और audit रखें।

Inspect, Deploy, Test और Drop

SHOW CREATE PROCEDURE customer_paid_summary;
SHOW PROCEDURE STATUS WHERE Db = DATABASE();

SELECT ROUTINE_NAME, SQL_DATA_ACCESS, SECURITY_TYPE
FROM information_schema.ROUTINES
WHERE ROUTINE_SCHEMA = DATABASE()
  AND ROUTINE_TYPE = 'PROCEDURE';

DROP PROCEDURE IF EXISTS list_customer_orders;
  1. Definitions source control/migrations में रखें।
  2. Explicit types और NULL/boundaries validate करें।
  3. Outputs, affected rows और SQLSTATEs test करें।
  4. Transaction ownership document करें।
  5. Write routines concurrency/locks test करें।
  6. Internal predicates index और plans inspect करें।
  7. Restore के बाद DEFINER/EXECUTE grants review करें।
  8. Many unrelated result sets avoid करें।
  9. Latency/frequency monitor करें।

आगे stored functions, transactions और prepared statements पढ़ें।

Official संदर्भ

Parameter modes, invocation, characteristics, privilege behavior और management official MySQL 8.4 manual से verify किए गए हैं।

अक्सर पूछे जाने वाले प्रश्न (FAQ)

MySQL stored procedure क्या है?
यह named stored routine है जो CALL से चलती है। IN, OUT, INOUT parameters ले सकती, multiple SQL statements चला सकती, result sets return और data change कर सकती है।
क्या DELIMITER server को भेजा जाने वाला SQL है?
नहीं। DELIMITER mysql client command है ताकि compound routine body के semicolons CREATE PROCEDURE को early end न करें। Other tools अलग delimiter handling दे सकते हैं।
IN, OUT और INOUT में क्या अंतर है?
IN value देता है; OUT अंदर NULL से शुरू होकर value लौटाता है; INOUT initial value लेकर change करके लौटाता है। OUT/INOUT CALL में commonly user variables use होते हैं।
क्या procedure automatically transaction शुरू करती है?
नहीं। Boundaries statements और session autocommit पर निर्भर हैं। Routine transaction own करे तो clearly document करें; callers independent nested transaction assume नहीं कर सकते।
क्या all business logic procedures में रखनी चाहिए?
नहीं। Database-centered operations, permission boundary और fewer round trips में useful हैं, पर portability, testing, versioning और application responsibilities भी देखें।
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

💻 लाइव कोड एडिटर

इस पेज के प्रोग्राम यहीं तैयार हैं — चलाएँ, बदलें और सीखें। कुछ भी इंस्टॉल किए बिना।
OneCompiler द्वारा संचालित। कोड एडिटर में अपने आप आ जाता है — Run दबाकर आउटपुट देखें। अगर एडिटर न खुले तो नए टैब में खोलें.