-
Notifications
You must be signed in to change notification settings - Fork 532
/
Copy path09.Stored Procedures and Functions.sql
236 lines (180 loc) · 5.66 KB
/
09.Stored Procedures and Functions.sql
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
/**************************************/
/* Stored Procedures */
/**************************************/
DELIMITER $$
CREATE PROCEDURE get_clients()
BEGIN
SELECT * FROM clients;
END $$
DELIMITER ;
/**************************************/
/* Call Stored Procedures */
/**************************************/
CALL get_clients();
/* get_invoices_with_balance to return all the invoices with balance > 0 */
DROP PROCEDURE IF EXISTS get_invoices_with_balance;
DELIMITER $$
CREATE PROCEDURE get_invoices_with_balance()
BEGIN
SELECT *
FROM invoices
WHERE (invoice_total - payment_total) > 0;
END $$
DELIMITER ;
CALL get_invoices_with_balance();
/**************************************/
/* DROP Stored Procedures */
/**************************************/
DROP PROCEDURE IF EXISTS get_clients;
/**************************************/
/* Parameters */
/**************************************/
DROP PROCEDURE IF EXISTS get_client_by_state;
DELIMITER $$
CREATE PROCEDURE get_client_by_state(p_state CHAR(2))
BEGIN
SELECT * FROM clients
WHERE state = p_state;
END $$
DELIMITER ;
CALL get_client_by_state('NY');
/* exercise */
/* return invoices for a given client */
DROP PROCEDURE IF EXISTS get_invoices_by_client;
DELIMITER $$
CREATE PROCEDURE get_invoices_by_client(p_client_name VARCHAR(50))
BEGIN
SELECT * FROM invoices i
JOIN clients c ON c.client_id = i.invoice_id
WHERE c.name = p_client_name;
END $$
DELIMITER ;
CALL get_invoices_by_client('Myworks');
/**************************************/
/* Parameters with DEFAULT values */
/**************************************/
-- set the state to CA if there is no parameters given
DROP PROCEDURE IF EXISTS get_client_by_state;
DELIMITER $$
CREATE PROCEDURE get_client_by_state(p_state CHAR(2))
BEGIN
IF p_state IS NULL THEN
SET p_state = 'CA';
END IF;
SELECT * FROM clients
WHERE state = p_state;
END $$
DELIMITER ;
CALL get_client_by_state(NULL);
-- get all clients, if there is no parameters given
DROP PROCEDURE IF EXISTS get_client_by_state;
DELIMITER $$
CREATE PROCEDURE get_client_by_state(p_state CHAR(2))
BEGIN
SELECT * FROM clients
WHERE state = IFNULL(p_state, state);
END $$
DELIMITER ;
CALL get_client_by_state(NULL);
/* Exercise */
/*stored procedure get_payments with two parameters
client_id INT(4),
payment_method_id TINYINT(1) => 0-255
parameters are optional and if not given, get all info
*/
DROP PROCEDURE IF EXISTS get_payments;
DELIMITER $$
CREATE PROCEDURE get_payments(p_client_id INT(4), p_payment_method_id TINYINT(1))
BEGIN
SELECT * FROM payments
WHERE client_id = IFNULL(p_client_id, client_id)
AND payment_method = IFNULL(p_payment_method_id, payment_method);
END $$
DELIMITER ;
CALL get_payments(5,2);
CALL get_payments(5,NULL);
CALL get_payments(NULL,1);
CALL get_payments(NULL,NULL);
/**************************************/
/* Parameters Validation */
/**************************************/
DROP PROCEDURE IF EXISTS make_payment;
DELIMITER $$
CREATE PROCEDURE make_payment(invoice_id INT, payment_amount DECIMAL(9,2), payment_date DATE)
BEGIN
IF payment_amount <= 0 THEN
SIGNAL SQLSTATE '22003'
SET MESSAGE_TEXT = 'Invalid Payment Amount';
END IF;
UPDATE invoices i
SET i.invoice_amount = payment_amount,
i.payment_date = payment_date
WHERE i.invoice_id = invoice_id;
END $$
DELIMITER ;
-- Testing
CALL mosh_sql_invoicing.make_payment(1, -345, '2020-05-01');
/**************************************/
/* Output Parameters */
/**************************************/
/*get unpaid invoices for a client */
DROP PROCEDURE IF EXISTS get_unpaid_invoices_for_client;
DELIMITER $$
CREATE PROCEDURE get_unpaid_invoices_for_client(client_id INT, OUT number_of_unpaid_invoices INT, OUT total_unpaid_amount INT)
BEGIN
SELECT COUNT(*), SUM(invoice_total)
INTO number_of_unpaid_invoices, total_unpaid_amount
FROM invoices i
WHERE i.client_id = client_id
AND payment_total = 0;
END $$
DELIMITER ;
-- testing
set @number_of_unpaid_invoices = 0;
set @total_unpaid_amount = 0;
call mosh_sql_invoicing.get_unpaid_invoices_for_client(3, @number_of_unpaid_invoices, @total_unpaid_amount);
select @number_of_unpaid_invoices, @total_unpaid_amount;
/**************************************/
/* Variables */
/**************************************/
-- User or Session Variables
set @total_unpaid_amount = 0;
-- Local Variables
DELIMITER $$
CREATE PROCEDURE get_risk_factor()
BEGIN
DECLARE risk_factor DECIMAL(9,2) DEFAULT 0;
DECLARE invoices_total DECIMAL(9,2);
DECLARE invoice_count INT;
SELECT COUNT(*), SUM(invoice_total)
INTO invoices_total, invoice_count
FROM invoices;
SET risk_factor = invoices_total / invoice_count * 5;
SELECT risk_factor;
END $$
DELIMITER ;
CALL get_risk_factor();
/***********************************************************/
/**************************************/
/* Functions */
/**************************************/
DROP FUNCTION IF EXISTS func_get_risk_factor_for_client;
DELIMITER $$
CREATE FUNCTION func_get_risk_factor_for_client(client_id INT)
RETURNS INTEGER
READS SQL DATA
BEGIN
DECLARE risk_factor DECIMAL(9,2) DEFAULT 0;
DECLARE invoices_total DECIMAL(9,2);
DECLARE invoice_count INT;
SELECT COUNT(*), SUM(invoice_total)
INTO invoices_total, invoice_count
FROM invoices i
WHERE i.client_id = client_id;
SET risk_factor = invoices_total / invoice_count * 5;
RETURN IFNULL(risk_factor,0);
END $$
DELIMITER ;
-- Testing
SELECT client_id, name, func_get_risk_factor_for_client(client_id) AS risk_factor
FROM clients;