-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathSQL_Cursors.sql
More file actions
141 lines (112 loc) · 3.47 KB
/
SQL_Cursors.sql
File metadata and controls
141 lines (112 loc) · 3.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
-- SQL_Cursors.sql
-- Guide to MySQL Cursors in Stored Procedures
CREATE DATABASE IF NOT EXISTS retail_db;
USE retail_db;
CREATE TABLE products (
product_id INT AUTO_INCREMENT PRIMARY KEY,
product_name VARCHAR(100) NOT NULL,
category VARCHAR(50),
price DECIMAL(10,2) NOT NULL,
stock_quantity INT DEFAULT 0
);
CREATE TABLE update_log (
log_id INT AUTO_INCREMENT PRIMARY KEY,
product_id INT,
old_stock INT,
new_stock INT,
update_time DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- Sample data
INSERT INTO products (product_name, category, price, stock_quantity) VALUES
('Laptop Pro', 'Electronics', 999.99, 45),
('Smartphone X', 'Electronics', 699.99, 80),
('Coffee Maker', 'Appliances', 49.99, 15),
('Wireless Headphones', 'Electronics', 89.99, 30),
('Blender', 'Appliances', 39.99, 10);
-- 1. Basic Cursor: Restock low-stock items
DELIMITER //
CREATE PROCEDURE RestockLowItems()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE v_id INT;
DECLARE v_name VARCHAR(100);
DECLARE v_stock INT;
DECLARE cur CURSOR FOR
SELECT product_id, product_name, stock_quantity
FROM products
WHERE stock_quantity < 40;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur;
read_loop: LOOP
FETCH cur INTO v_id, v_name, v_stock;
IF done THEN
LEAVE read_loop;
END IF;
INSERT INTO update_log (product_id, old_stock, new_stock)
VALUES (v_id, v_stock, v_stock + 50);
UPDATE products
SET stock_quantity = stock_quantity + 50
WHERE product_id = v_id;
END LOOP;
CLOSE cur;
END //
DELIMITER ;
-- Test
CALL RestockLowItems();
SELECT * FROM update_log;
SELECT product_name, stock_quantity FROM products WHERE stock_quantity > 40;
-- 2. Cursor with conditional update
DELIMITER //
CREATE PROCEDURE ApplyDiscount()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE v_id INT;
DECLARE v_price DECIMAL(10,2);
DECLARE price_cur CURSOR FOR
SELECT product_id, price FROM products WHERE category = 'Electronics';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN price_cur;
discount_loop: LOOP
FETCH price_cur INTO v_id, v_price;
IF done THEN
LEAVE discount_loop;
END IF;
IF v_price > 500 THEN
UPDATE products SET price = price * 0.9 WHERE product_id = v_id;
END IF;
END LOOP;
CLOSE price_cur;
END //
DELIMITER ;
-- Test
CALL ApplyDiscount();
SELECT product_name, price FROM products WHERE category = 'Electronics';
-- Exercises
-- Exercise 1: Cursor to log high-price products (>500)
DELIMITER //
CREATE PROCEDURE LogPremiumProducts()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE v_id INT;
DECLARE v_name VARCHAR(100);
DECLARE v_price DECIMAL(10,2);
DECLARE prem_cur CURSOR FOR
SELECT product_id, product_name, price FROM products WHERE price > 500;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN prem_cur;
log_loop: LOOP
FETCH prem_cur INTO v_id, v_name, v_price;
IF done THEN LEAVE log_loop; END IF;
INSERT INTO update_log (product_id, old_stock, new_stock)
VALUES (v_id, v_price, NULL); -- Reuse log table creatively
END LOOP;
CLOSE prem_cur;
END //
DELIMITER ;
-- Cleanup
DROP PROCEDURE IF EXISTS RestockLowItems;
DROP PROCEDURE IF EXISTS ApplyDiscount;
DROP PROCEDURE IF EXISTS LogPremiumProducts;
DROP TABLE update_log;
DROP TABLE products;
DROP DATABASE retail_db;