List of commits:
Subject Hash Author Date (UTC)
Worked on migrating code to snippets. 1ce6f6ba150a1cace57445330801e8b17f6c3044 aubert@math.cnrs.fr 2020-04-22 04:15:37
Disabled Scrolling of sql files in html and enabled resize option 87d4ef4185fe48a7503724eb98a6c486c351ddee pveeral@augusta.edu 2020-04-21 15:49:36
Updated list of bugs. 17827a6a5b127fa6449b495c1e07359da4682100 aubert@math.cnrs.fr 2020-04-20 19:24:01
Worked on nosql chapter. 38dfcfffce7c06d0eab7256a7a5be1e2481a8505 aubert@math.cnrs.fr 2020-04-20 17:52:55
ALT in img folder 6e6469575d825f6c7360b88d6b387aee709b643c pveeral@augusta.edu 2020-04-20 15:26:47
Cleaned up bib file. 505b1000bca31e4d833bf7739d02d2b7e727e69b aubert@math.cnrs.fr 2020-04-20 05:03:18
rapid adjustments in contrib beb43332953ec4e2a8e4376a90ce58b1234eadba aubert@math.cnrs.fr 2020-04-20 00:10:44
Updated CONTRIB.md c29d920e1efbc84766a3caafc0db2fcab4220b32 pveeral@augusta.edu 2020-04-19 19:28:45
testing 4ece7ba3d5c5d99361ef5eac92bb0848f2ea5318 pveeral@augusta.edu 2020-04-19 18:27:50
Small edit, correcting maefile. 7baa188be7d322e5288b498afbb7beaa96a9770b aubert@math.cnrs.fr 2020-04-19 07:36:08
Cleaned latex files. 79b68f7b709ddeebc8133f7962fe5aabb3376304 aubert@math.cnrs.fr 2020-04-19 06:22:30
Minor corrections in installation manual. 436cee8616c25ccbed8bc406d988c2b4d28420f8 aubert@math.cnrs.fr 2020-04-19 06:19:04
Minor corrections in installation manual. cb8cdfbd506a1344c81aecda055165cc1ca54ece aubert@math.cnrs.fr 2020-04-19 06:17:52
Working on install manual. 3702c6437ee163eb4a61b4d69cffee8c8a76dc3d aubert@math.cnrs.fr 2020-04-19 06:04:22
Worked on makefiles and example file. 4255d5e85bb684349f7f7798455dd8b3a273254b aubert@math.cnrs.fr 2020-04-19 04:56:53
Re-idented some of the code. 124375e6bed1edb96d1bb4bcec8f111c8a3a1197 aubert@math.cnrs.fr 2020-04-19 03:10:02
Java indentation 2b317a12b7ab52bdca576a1bb46b2a2ce295464f guest 2020-04-18 22:21:04
test 6fefa044794ff1d74a3d2493556c836b3dd97e74 guest 2020-04-18 22:18:44
Java indentation 5b0e0eb38484a8c67517a36a438f148bd5efa740 guest 2020-04-18 22:14:01
Worked on install notes. b46b931ef11e3cb7dfe87c7f91ec9d5c558567e6 aubert@math.cnrs.fr 2020-04-17 05:22:20
Commit 1ce6f6ba150a1cace57445330801e8b17f6c3044 - Worked on migrating code to snippets.
Author: aubert@math.cnrs.fr
Author date (UTC): 2020-04-22 04:15
Committer name: aubert@math.cnrs.fr
Committer date (UTC): 2020-04-22 04:15
Parent(s): 87d4ef4185fe48a7503724eb98a6c486c351ddee
Signer:
Signing key:
Signing status: N
Tree: 1b68ec7f5d30168cf9685a6d387eff6d8019cadb
File Lines added Lines deleted
KNOWN_BUGS.md 2 17
notes/code/sql/HW_Avg.sql 3 2
notes/code/sql/HW_ProcedureExamples.sql 18 28
notes/code/sql/HW_ProfExample.sql 255 0
notes/code/sql/HW_Short.sql 20 0
notes/code/sql/HW_TriggerExample.sql 27 48
notes/lectures_notes.md 110 237
notes/style/style.css 2 1
notes/temp.md 6 4
File KNOWN_BUGS.md changed (mode: 100644) (index 4613c29..c594f7d)
... ... Attempt on the left:
181 181 background-size:0 0!important; background-size:0 0!important;
182 182 */ */
183 183 } }
184 ```
185
184 ```
185
186 186 Almost there? Almost there?
187 187
188 188 ```{.css} ```{.css}
 
... ... Almost there?
214 214 ``` ```
215 215
216 216 - add actual links in code. - add actual links in code.
217 - Remove
218 217
219 ```{.css}
220 @media screen {
221 code.sourceCode > span > a:first-child::before { text-decoration: underline; }
222 }
223 ```
224
225 - What's the point of
226
227 ```{.css}
228 .sourceCode:after {
229 content: attr(data-caption);
230 font-weight:bold;
231 }
232 ```
233 218 - hover should probably be on line number. - hover should probably be on line number.
234 219
235 220 PDF PDF
File notes/code/sql/HW_Avg.sql changed (mode: 100644) (index 7250e6a..f73583d)
1 /* code/sql/HW_Avg.sql */
2
3 1 DROP SCHEMA IF EXISTS HW_Avg; DROP SCHEMA IF EXISTS HW_Avg;
4 2 CREATE SCHEMA HW_Avg; CREATE SCHEMA HW_Avg;
5 3 USE HW_AVG; USE HW_AVG;
6 4
5 -- start snippet show-avg
6 /* code/sql/HW_Avg.sql */
7 7 CREATE TABLE TEST( CREATE TABLE TEST(
8 8 Test INT Test INT
9 9 ); );
 
... ... INSERT INTO TEST VALUES (null), (0), (10);
12 12
13 13 SELECT AVG(Test) FROM TEST; SELECT AVG(Test) FROM TEST;
14 14 -- Returns 5.0 -- Returns 5.0
15 -- end snippet show-avg
File notes/code/sql/HW_ProcedureExamples.sql changed (mode: 100644) (index f5bfafa..24b1670)
1 /* code/sql/HW_ProcedureExamples.sql */
2
3 1 DROP SCHEMA IF EXISTS HW_ProcedureExamples; DROP SCHEMA IF EXISTS HW_ProcedureExamples;
4 2 CREATE SCHEMA HW_ProcedureExamples; CREATE SCHEMA HW_ProcedureExamples;
5 3 USE HW_ProcedureExamples; USE HW_ProcedureExamples;
6 4
7 /*
8 A "procedure" is a serie of statements stored in a schema,
9 that can easily be executed repeatedly.
10 https://dev.mysql.com/doc/refman/8.0/en/create-procedure.html
11 https://mariadb.com/kb/en/library/create-procedure/
12 */
13
14
5 -- start snippet procedure-1
6 /* code/sql/HW_ProcedureExamples.sql */
15 7 CREATE TABLE STUDENT( CREATE TABLE STUDENT(
16 8 Login INT PRIMARY KEY, Login INT PRIMARY KEY,
17 9 Name VARCHAR(30), Name VARCHAR(30),
 
... ... CREATE TABLE STUDENT(
19 11 Email VARCHAR(30) Email VARCHAR(30)
20 12 ); );
21 13
22 INSERT INTO STUDENT VALUES (123, "Test A", "CS", "a@a.edu"),
23 (124, "Test B", "IT", "b@a.edu"),
24 (125, "Test C", "CYBR", "c@a.edu");
14 INSERT INTO STUDENT VALUES
15 (123, "Test A", "CS", "a@a.edu"),
16 (124, "Test B", "IT", "b@a.edu"),
17 (125, "Test C", "CYBR", "c@a.edu");
18 -- end snippet procedure-1
25 19
26 DELIMITER // -- This tells mysql not to mistake the ; below for the end of the procedure definition.
27 /*
28 We temporarily alter the language, and make the delimiter being //.
29 $$ is often used too, and the documentation, at https://dev.mysql.com/doc/refman/8.0/en/stored-programs-defining.html, reads:
30 " You can redefine the delimiter to a string other than //,
31 " and the delimiter can consist of a single character or multiple characters.
32 " You should avoid the use of the backslash (\) character because that is the escape character for MySQL.
33 I am assuming that using the minus sign twice is also a poor choice.
34 */
20 -- start snippet procedure-2
21 DELIMITER //
35 22 CREATE PROCEDURE STUDENTLIST() CREATE PROCEDURE STUDENTLIST()
36 23 BEGIN BEGIN
37 SELECT * FROM STUDENT; -- This ";" is not the end of the procedure definition!
24 SELECT * FROM STUDENT;
25 -- This ";" is not the end of the procedure definition!
38 26 END; END;
39 27 // -- This is the delimiter that marks the end of the procedure definition. // -- This is the delimiter that marks the end of the procedure definition.
40 28 DELIMITER ; -- Now, we want ";" to be the "natural" delimiter again. DELIMITER ; -- Now, we want ";" to be the "natural" delimiter again.
41 29
42 CALL STUDENTLIST();
43
30 CALL STUDENTLIST();
31 -- end snippet procedure-2
44 32
33 -- start snippet procedure-3
45 34 DELIMITER // DELIMITER //
46 35 CREATE PROCEDURE STUDENTLOGIN(NameP VARCHAR(30)) CREATE PROCEDURE STUDENTLOGIN(NameP VARCHAR(30))
47 36 BEGIN BEGIN
 
... ... END;
53 41 DELIMITER ; DELIMITER ;
54 42
55 43 SHOW CREATE PROCEDURE STUDENTLOGIN; SHOW CREATE PROCEDURE STUDENTLOGIN;
44 -- This display information about the procedure just created.
56 45
57 CALL STUDENTLOGIN("Test A"); -- We can pass quite naturally an argument to our procedure.
46 -- We can pass quite naturally an argument to our procedure.
47 CALL STUDENTLOGIN("Test A");
48 -- end snippet procedure-3
File notes/code/sql/HW_ProfExample.sql added (mode: 100644) (index 0000000..41f78db)
1 /* code/sql/HW_ProfExample.sql */
2
3 DROP SCHEMA IF EXISTS HW_ProfExample;
4 CREATE SCHEMA HW_ProfExample;
5 USE HW_ProfExample;
6
7 -- start snippet tables-1
8 /* code/sql/HW_ProfExample.sql */
9
10 CREATE TABLE PROF(
11 Login VARCHAR(25) PRIMARY KEY,
12 Name VARCHAR(25),
13 Department CHAR(5)
14 );
15
16 CREATE TABLE DEPARTMENT(
17 Code CHAR(5) PRIMARY KEY,
18 Name VARCHAR(25),
19 Head VARCHAR(25),
20 FOREIGN KEY (Head) REFERENCES PROF(Login)
21 ON UPDATE CASCADE
22 );
23
24 ALTER TABLE PROF ADD FOREIGN KEY (Department)
25 REFERENCES DEPARTMENT(Code);
26 -- end snippet tables-1
27
28 -- start snippet tables-2
29 CREATE TABLE STUDENT(
30 Login VARCHAR(25) PRIMARY KEY,
31 Name VARCHAR(25),
32 Registered DATE,
33 Major CHAR(5),
34 FOREIGN KEY (Major) REFERENCES DEPARTMENT(Code)
35 );
36
37 CREATE TABLE GRADE(
38 Login VARCHAR(25),
39 Grade INT,
40 PRIMARY KEY(Login, Grade),
41 FOREIGN KEY (Login) REFERENCES STUDENT(Login)
42 );
43 -- end snippet tables-2
44
45
46 -- start snippet insert-1
47 INSERT INTO DEPARTMENT VALUES
48 ('MATH', 'Mathematics', NULL),
49 ('CS', 'Computer Science', NULL);
50 -- end snippet insert-1
51
52 -- start snippet insert-2
53 INSERT INTO DEPARTMENT (Code, Name) VALUES
54 ('CYBR', 'Cyber Secturity');
55 -- end snippet insert-2
56
57 -- start snippet insert-3
58 INSERT INTO PROF (Login, Department, Name) VALUES
59 ('caubert', 'CS', 'Clément Aubert');
60
61 INSERT INTO PROF (Login, Name, Department) VALUES
62 ('aturing', 'Alan Turing', 'CS'),
63 ('perdos', 'Paul Erdős', 'MATH'),
64 ('bgates', 'Bill Gates', 'CYBR');
65
66 INSERT INTO STUDENT (Login, Name, Registered, Major) VALUES
67 ('jrakesh', 'Jalal Rakesh', DATE'2017-12-01', 'CS'),
68 ('svlatka', 'Sacnite Vlatka', '2015-03-12', 'MATH'),
69 ('cjoella', 'Candice Joella', '20120212', 'CYBR'),
70 ('aalyx', 'Ava Alyx', 20121011, 'CYBR'),
71 ('caubert', 'Clément Aubert', NULL, 'CYBR');
72
73 INSERT INTO GRADE VALUES
74 ('jrakesh', 3.8),
75 ('svlatka', 2.5);
76 -- end snippet insert-3
77
78 -- start snippet select-update
79 SELECT Login FROM STUDENT;
80
81 UPDATE DEPARTMENT
82 SET Head = 'aturing'
83 WHERE Code = 'MATH';
84
85 UPDATE DEPARTMENT
86 SET Head = 'bgates'
87 WHERE Code = 'CS' OR Code = 'CYBR';
88
89 SELECT Login
90 FROM STUDENT
91 WHERE NOT Major = 'CYBR';
92
93 SELECT Login, Name
94 FROM PROF
95 WHERE Department = 'CS';
96
97 SELECT Login
98 FROM STUDENT
99 WHERE Major = 'CYBR'
100 AND
101 Registered > DATE'20121001';
102
103 SELECT Login
104 FROM STUDENT
105 WHERE Name LIKE 'Ava%';
106
107 SELECT Name
108 FROM PROF
109 WHERE Login LIKE '_aubert';
110 -- end snippet select-update
111
112 -- start snippet null
113 INSERT INTO DEPARTMENT Values ('Hist', 'History', NULL);
114 SELECT * FROM DEPARTMENT WHERE Head IS NULL;
115 SELECT * FROM DEPARTMENT WHERE Head IS NOT NULL;
116 SELECT COUNT(*) FROM GRADE WHERE Grade IS NULL;
117 -- end snippet null
118
119 -- start snippet order-by
120 SELECT Login FROM GRADE
121 WHERE Grade > 2.0
122 ORDER BY Grade;
123
124 SELECT Login FROM GRADE
125 WHERE Grade > 2.0
126 ORDER BY Grade DESC;
127
128 SELECT Login, Major FROM STUDENT
129 ORDER BY Major, Name;
130 -- end snippet order-by
131
132 -- start snippet select-project-join-1
133 SELECT Login
134 FROM PROF, DEPARTMENT
135 WHERE DEPARTMENT.Name = "Mathematics"
136 AND
137 Department = Code;
138 -- end snippet select-project-join-1
139
140 -- start snippet select-project-join-2
141 SELECT Name
142 FROM STUDENT, GRADE
143 WHERE Grade > 3.0
144 AND
145 STUDENT.Login = GRADE.Login;
146 -- end snippet select-project-join-2
147
148 -- start snippet select-project-join-3
149 SELECT PROF.Name
150 FROM PROF, DEPARTMENT, STUDENT
151 WHERE STUDENT.Name = "Ava Alyx"
152 AND
153 STUDENT.Major = DEPARTMENT.Code
154 AND
155 DEPARTMENT.Head = PROF.Login;
156 -- end snippet select-project-join-3
157
158 -- start snippet alias-1
159 SELECT PROF.Name
160 FROM PROF, DEPARTMENT, STUDENT AS B
161 WHERE B.Name = "Ava Alyx"
162 AND
163 B.Major = DEPARTMENT.Code
164 AND
165 DEPARTMENT.Head = PROF.Login;
166 -- end snippet alias-1
167
168 -- start snippet alias-2
169 SELECT A.Name
170 FROM PROF AS A, DEPARTMENT AS B, STUDENT AS C
171 WHERE C.Name = "Ava Alyx"
172 AND
173 C.Major = B.Code
174 AND
175 B.Head = A.Login;
176 -- end snippet alias-2
177
178 -- start snippet alias-3
179 SELECT Others.Login
180 FROM GRADE AS Mine, GRADE AS Others
181 WHERE Mine.Login = "aalyx"
182 AND
183 Mine.Grade < Others.Grade;
184 -- end snippet alias-3
185
186 -- start snippet alias-4
187 SELECT JOINT.Login
188 FROM PROF AS PROJECT, PROF AS JOINT
189 WHERE PROJECT.Login = "caubert"
190 AND
191 PROJECT.Department = JOINT.Department;
192 -- end snippet alias-4
193
194 -- start snippet alias-5
195 SELECT Fellow.Name AS "Fellow of Ava"
196 FROM STUDENT AS Ava, STUDENT AS Fellow
197 WHERE Ava.Name = "Ava Alyx"
198 AND
199 Fellow.Major = Ava.Major
200 AND
201 NOT Fellow.Login = Ava.Login;
202 -- end snippet alias-5
203
204 -- start snippet nested-1
205 SELECT Login FROM GRADE
206 WHERE Grade >
207 (SELECT AVG(Grade) FROM GRADE);
208 -- end snippet nested-1
209
210 -- start snippet nested-2
211 SELECT Login FROM GRADE
212 WHERE Grade >=
213 ALL (SELECT Grade FROM GRADE WHERE Grade IS NOT NULL);
214 -- end snippet nested-2
215
216 -- start snippet max
217 SELECT Login FROM GRADE
218 WHERE Grade >=
219 (SELECT MAX(Grade) FROM GRADE);
220 -- end snippet max
221
222 -- start snippet whodunit
223 SELECT Login
224 FROM PROF
225 WHERE DEPARTMENT IN ( SELECT Major
226 FROM STUDENT
227 WHERE Login LIKE '%a');
228 -- end snippet whodunit
229
230 -- start snippet transf-1a
231 SELECT Login
232 FROM PROF
233 WHERE DEPARTMENT = ( SELECT Major
234 FROM STUDENT
235 WHERE Login = "cjoella");
236 -- end snippet transf-1a
237
238 -- start snippet transf-1b
239 SELECT PROF.Login
240 FROM PROF, STUDENT
241 WHERE DEPARTMENT = Major AND STUDENT.Login = "cjoella";
242 -- end snippet transf-1b
243
244 -- start snippet transf-2a
245 SELECT Name
246 FROM STUDENT, GRADE
247 WHERE Grade > 3.0
248 AND
249 STUDENT.Login = GRADE.Login;
250 -- end snippet transf-2a
251
252 -- start snippet transf-2b
253 SELECT Name FROM STUDENT
254 WHERE Login IN (SELECT Login FROM GRADE WHERE Grade > 3.0);
255 -- end snippet transf-2b
File notes/code/sql/HW_Short.sql added (mode: 100644) (index 0000000..0db4199)
1 DROP SCHEMA IF EXISTS HW_Short;
2 CREATE SCHEMA HW_Short;
3 USE HW_Short;
4
5 -- start snippet solution
6 /* code/sql/HW_Short.sql */
7 CREATE TABLE A(
8 Att1 INT PRIMARY KEY,
9 Att2 INT
10 );
11
12 CREATE TABLE B(
13 Att3 INT PRIMARY KEY,
14 Att4 INT,
15 FOREIGN KEY (Att4) REFERENCES A(Att1)
16 );
17
18 INSERT INTO A VALUES (1, 2);
19 INSERT INTO B VALUES (3, 1);
20 -- end snippet solution
File notes/code/sql/HW_TriggerExample.sql changed (mode: 100644) (index 72a8ab5..48f4c77)
1 1 /* code/sql/HW_TriggerExample.sql */ /* code/sql/HW_TriggerExample.sql */
2 2
3 3 DROP SCHEMA IF EXISTS HW_TriggerExample; DROP SCHEMA IF EXISTS HW_TriggerExample;
4 -- To drop only a trigger, you can use
5 --DROP TRIGGER IF EXISTS HW_TriggerExample.NUMBER_OF_STUDENT_INC;
6 --DROP TRIGGER IF EXISTS HW_TriggerExample.NUMBER_OF_STUDENT_DEC;
4 7 CREATE SCHEMA HW_TriggerExample; CREATE SCHEMA HW_TriggerExample;
5 8 USE HW_TriggerExample; USE HW_TriggerExample;
6 9
10 -- start snippet trigger-1
7 11 CREATE TABLE STUDENT( CREATE TABLE STUDENT(
8 Login VARCHAR(30) PRIMARY KEY,
12 Login VARCHAR(30) PRIMARY KEY,
9 13 Average Float Average Float
10 14 ); );
11 15
12
13 SET @number_of_student = 0;
14
15 /*
16 SQL supports some primitive form of variables.
17 cf.
18 https://dev.mysql.com/doc/refman/8.0/en/user-variables.html
19 https://mariadb.com/kb/en/library/user-defined-variables/
20 There is no "clear" form of type
21 https://dev.mysql.com/doc/refman/8.0/en/user-variables.html
22 reads:
23 " In addition, the default result type of a variable is based on
24 " its type at the beginning of the statement. This may have unintended
25 " effects if a variable holds a value of one type at the beginning of a
26 " statement in which it is also assigned a new value of a different type.
27
28 " To avoid problems with this behavior, either do not assign a value to
29 " and read the value of the same variable within a single statement, or else
30 " set the variable to 0, 0.0, or '' to define its type before you use it.
31
32 In other words, mysql just "guess" the type of your value and go with it.
33 */
16 CREATE TABLE GRADE(
17 Student VARCHAR(30),
18 Exam VARCHAR(30),
19 Grade INT,
20 PRIMARY KEY(Student, Exam),
21 FOREIGN KEY (Student) REFERENCES STUDENT(Login)
22 );
23 -- end snippet trigger-1
34 24
35 /*
36 We can create a trigger to count the number
37 of times something was inserted in our STUDENT
38 table.
39 */
25 -- start snippet trigger-2
26 SET @number_of_student = 0;
40 27
41 CREATE TRIGGER NUMBER_OF_STUDENT
28 CREATE TRIGGER NUMBER_OF_STUDENT_INC
42 29 AFTER INSERT ON STUDENT AFTER INSERT ON STUDENT
43 30 FOR EACH ROW SET @number_of_student = @number_of_student + 1; FOR EACH ROW SET @number_of_student = @number_of_student + 1;
31 -- end snippet trigger-2
44 32
45 33 INSERT INTO STUDENT(Login) VALUES ("A"), ("B"), ("C"), ("D"); INSERT INTO STUDENT(Login) VALUES ("A"), ("B"), ("C"), ("D");
46 34
 
... ... SELECT @number_of_student AS 'Total number of student'; -- And the counter knows
53 40 when a student is removed from our table! when a student is removed from our table!
54 41 */ */
55 42
56 CREATE TRIGGER NUMBER_OF_STUDENT
43 CREATE TRIGGER NUMBER_OF_STUDENT_DEC
57 44 AFTER DELETE ON STUDENT AFTER DELETE ON STUDENT
58 45 FOR EACH ROW SET @number_of_student = @number_of_student - 1; FOR EACH ROW SET @number_of_student = @number_of_student - 1;
59 46
 
... ... DELETE FROM STUDENT WHERE Login = "D" || Login = "E";
62 49 SELECT COUNT(*) FROM STUDENT; -- Note that our previous query deleted only one student. SELECT COUNT(*) FROM STUDENT; -- Note that our previous query deleted only one student.
63 50 SELECT @number_of_student AS 'Total number of student'; -- And the counter knows it. SELECT @number_of_student AS 'Total number of student'; -- And the counter knows it.
64 51
65 /*
66 Let us now create a table for each individal grade,
67 and a trigger to calculate the average for us.
68 Note that the trigger will need to manipulate two tables
69 at the same time.
70 */
71
72 CREATE TABLE GRADE(
73 Student VARCHAR(30),
74 Exam VARCHAR(30),
75 Grade INT,
76 PRIMARY KEY(Student, Exam),
77 FOREIGN KEY (Student) REFERENCES STUDENT(Login)
78 );
52 -- start snippet trigger-3
79 53
80 54 CREATE TRIGGER STUDENT_AVERAGE CREATE TRIGGER STUDENT_AVERAGE
81 55 AFTER INSERT ON GRADE AFTER INSERT ON GRADE
82 56 FOR EACH ROW -- Woh, a whole query inside our trigger! FOR EACH ROW -- Woh, a whole query inside our trigger!
83 57 UPDATE STUDENT UPDATE STUDENT
84 58 SET STUDENT.Average = SET STUDENT.Average =
85 (SELECT AVG(Grade) FROM GRADE WHERE GRADE.Student = STUDENT.Login)
86 WHERE STUDENT.Login = NEW.Student; -- The "NEW" keyword here refers to the "new" entry
59 (SELECT AVG(Grade)
60 FROM GRADE
61 WHERE GRADE.Student = STUDENT.Login)
62 WHERE STUDENT.Login = NEW.Student;
63 -- The "NEW" keyword here refers to the "new" entry
87 64 -- that is being inserted by the INSERT statement triggering the trigger. -- that is being inserted by the INSERT statement triggering the trigger.
65 -- end snippet trigger-3
88 66
89 67 INSERT INTO GRADE VALUES INSERT INTO GRADE VALUES
90 68 ("A", "Exam 1", 50), ("A", "Exam 1", 50),
 
... ... INSERT INTO GRADE VALUES
93 71 ("B", "Exam 2", 100); ("B", "Exam 2", 100);
94 72
95 73 SELECT * FROM GRADE; SELECT * FROM GRADE;
96 SELECT * FROM STUDENT; -- Tada, all the averages have been computed!
74 SELECT * FROM STUDENT;
75 -- Tada, all the averages have been computed!
97 76 -- Note also that the student "C" does not have an average! -- Note also that the student "C" does not have an average!
File notes/lectures_notes.md changed (mode: 100644) (index 29afcce..cccf7cf)
... ... DEPARTMENT(Code (PK), Name, Head (FK to PROF.Login))
1971 1971 ](fig/rel_mod/professor_department) ](fig/rel_mod/professor_department)
1972 1972 \ \
1973 1973
1974 ```
1975 CREATE TABLE PROF(
1976 Login VARCHAR(25) PRIMARY KEY,
1977 Name VARCHAR(25),
1978 Department CHAR(5)
1979 );
1980
1981 CREATE TABLE DEPARTMENT(
1982 Code CHAR(5) PRIMARY KEY,
1983 Name VARCHAR(25),
1984 Head VARCHAR(25),
1985 FOREIGN KEY (Head) REFERENCES PROF(Login)
1986 ON UPDATE CASCADE
1987 );
1988 1974
1989 ALTER TABLE PROF ADD FOREIGN KEY (Department)
1990 REFERENCES DEPARTMENT(Code);
1991 ```
1975 ```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=tables-1}
1976 ```
1992 1977
1993 1978 Note the structure of the `ALTER TABLE` command: Note the structure of the `ALTER TABLE` command:
1994 1979
 
... ... Note the structure of the `ALTER TABLE` command:
1996 1981 - … `KEY (Department) REFERENCES (Code);`⇒ error - … `KEY (Department) REFERENCES (Code);`⇒ error
1997 1982 - … `KEY PROF(Department) REFERENCES DEPARTMENT(Code);` ⇒ ok - … `KEY PROF(Department) REFERENCES DEPARTMENT(Code);` ⇒ ok
1998 1983
1999 ```
2000 CREATE TABLE STUDENT(
2001 Login VARCHAR(25) PRIMARY KEY,
2002 Name VARCHAR(25),
2003 Registered DATE,
2004 Major CHAR(5),
2005 FOREIGN KEY (Major) REFERENCES DEPARTMENT(Code)
2006 );
2007
2008 CREATE TABLE GRADE(
2009 Login VARCHAR(25),
2010 Grade INT,
2011 PRIMARY KEY(Login, Grade),
2012 FOREIGN KEY (Login) REFERENCES STUDENT(Login)
2013 );
2014 ```
1984 ```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=tables-2}
1985 ```
2015 1986
2016 1987 #### Populating #### Populating
2017 1988
2018 1989 We can insert multiple values at once: We can insert multiple values at once:
2019 1990
2020 ```
2021 INSERT INTO DEPARTMENT VALUES
2022 ('MATH', 'Mathematics', NULL),
2023 ('CS', 'Computer Science', NULL);
2024 ```
1991 ```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=insert-1}
1992 ```
2025 1993
2026 1994 We can specify which attributes we are giving: We can specify which attributes we are giving:
2027 1995
2028 ```
2029 INSERT INTO DEPARTMENT (Code, Name) VALUES
2030 ('CYBR', 'Cyber Secturity');
2031 ```
1996 ```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=insert-2}
1997 ```
2032 1998
2033 1999 And we can even specify the order (even the trivial one): And we can even specify the order (even the trivial one):
2034 2000
2035 ```
2036 INSERT INTO PROF (Login, Department, Name) VALUES
2037 ('caubert', 'CS', 'Clément Aubert');
2038
2039 INSERT INTO PROF (Login, Name, Department) VALUES
2040 ('aturing', 'Alan Turing', 'CS'),
2041 ('perdos', 'Paul Erdős', 'MATH'),
2042 ('bgates', 'Bill Gates', 'CYBR');
2043
2044 INSERT INTO STUDENT (Login, Name, Registered, Major) VALUES
2045 ('jrakesh', 'Jalal Rakesh', DATE'2017-12-01', 'CS'),
2046 ('svlatka', 'Sacnite Vlatka', '2015-03-12', 'MATH'),
2047 ('cjoella', 'Candice Joella', '20120212', 'CYBR'),
2048 ('aalyx', 'Ava Alyx', 20121011, 'CYBR'),
2049 ('caubert', 'Clément Aubert', NULL, 'CYBR');
2050
2051 INSERT INTO GRADE VALUES
2052 ('jrakesh', 3.8),
2053 ('svlatka', 2.5);
2054 ```
2001 ```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=insert-3}
2002 ```
2055 2003
2056 2004 Note the date literals. Note the date literals.
2057 2005
 
... ... Order of clauses does not matter, not even for optimization purpose.
2063 2011 UPDATE <table> UPDATE <table>
2064 2012 SET <attribute1> = <value1>, <attribute2> = <value2>, … SET <attribute1> = <value1>, <attribute2> = <value2>, …
2065 2013 WHERE <condition>; WHERE <condition>;
2014 ```
2066 2015
2016 ```
2067 2017 SELECT <attribute list, called projection attributes> SELECT <attribute list, called projection attributes>
2068 2018 FROM <table list> FROM <table list>
2069 2019 WHERE <condition>; WHERE <condition>;
2020 ```
2070 2021
2022 ```
2071 2023 DELETE FROM <table list> DELETE FROM <table list>
2072 2024 WHERE <condition>; WHERE <condition>;
2073 2025 ``` ```
 
... ... Conditions can
2093 2045 - `_` will match one character (any character), `%` will match any number of character, - `_` will match one character (any character), `%` will match any number of character,
2094 2046 - advanced regular expression possible using the `REGEXP` keyword. - advanced regular expression possible using the `REGEXP` keyword.
2095 2047
2096 ```
2097 SELECT Login FROM STUDENT;
2098
2099 UPDATE DEPARTMENT
2100 SET Head = 'aturing'
2101 WHERE Code = 'MATH';
2102
2103 UPDATE DEPARTMENT
2104 SET Head = 'bgates'
2105 WHERE Code = 'CS' OR Code = 'CYBR';
2106
2107 SELECT Login
2108 FROM STUDENT
2109 WHERE NOT Major = 'CYBR';
2110
2111 SELECT Login, Name
2112 FROM PROF
2113 WHERE Department = 'CS';
2114
2115 SELECT Login
2116 FROM STUDENT
2117 WHERE Major = 'CYBR'
2118 AND
2119 Registered > DATE'20121001';
2120
2121 SELECT Login
2122 FROM STUDENT
2123 WHERE Name LIKE 'Ava%';
2124
2125 SELECT Name
2126 FROM PROF
2127 WHERE Login LIKE '_aubert';
2128 ```
2048 ```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=select-update}
2049 ```
2129 2050
2130 2051 Note that `LIKE` is by default case-insensitive, both in [MariaDB](https://mariadb.com/kb/en/like/) and in [MySQL](https://dev.mysql.com/doc/refman/8.0/en/case-sensitivity.html). Note that `LIKE` is by default case-insensitive, both in [MariaDB](https://mariadb.com/kb/en/like/) and in [MySQL](https://dev.mysql.com/doc/refman/8.0/en/case-sensitivity.html).
2131 2052 The `COLLATE` operator can be used to force the search to be case-sensitive, as well as `LIKE BINARY`. The `COLLATE` operator can be used to force the search to be case-sensitive, as well as `LIKE BINARY`.
 
... ... U | U
2190 2111
2191 2112 You can test if a value is `NULL` with `IS NULL`. You can test if a value is `NULL` with `IS NULL`.
2192 2113
2193 ```
2194 INSERT INTO DEPARTMENT Values ('Hist', 'History', NULL);
2195 SELECT * FROM DEPARTMENT WHERE Head IS NULL;
2196 SELECT * FROM DEPARTMENT WHERE Head IS NOT NULL;
2197 SELECT COUNT(*) FROM GRADE WHERE Grade IS NULL;
2198 ```
2114 ```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=null}
2115 ```
2199 2116
2200 2117 Note that you can not use `IS` to compare values: this key word is reserved to test if a value is (not) `NULL`, and nothing else. Note that you can not use `IS` to compare values: this key word is reserved to test if a value is (not) `NULL`, and nothing else.
2201 2118
 
... ... There is also `INTERSECT` and `EXCEPT` in the specification, but MySQL does not
2282 2199
2283 2200 You can have `ORDER BY` specifications: You can have `ORDER BY` specifications:
2284 2201
2285 ```
2286 SELECT Login FROM GRADE
2287 WHERE Grade > 2.0
2288 ORDER BY Grade;
2289
2290 SELECT Login FROM GRADE
2291 WHERE Grade > 2.0
2292 ORDER BY Grade DESC;
2293
2294 SELECT Login, Major FROM STUDENT
2295 ORDER BY Major, Name;
2296 ```
2202 ```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=order-by}
2203 ```
2297 2204
2298 2205 `ORDER BY` order by ascending order by default. `ORDER BY` order by ascending order by default.
2299 2206
 
... ... returns the number of _different names_ (which in this case is the same as the n
2321 2228
2322 2229 Note that `AVG` returns the average of all **non-`NULL`** values, as we can see on the following example: Note that `AVG` returns the average of all **non-`NULL`** values, as we can see on the following example:
2323 2230
2324 ```{.sqlmysql .numberLines include=code/sql/HW_Avg.sql}
2231 ```{.sqlmysql .numberLines include=code/sql/HW_Avg.sql snippet=show-avg}
2325 2232 ``` ```
2326 2233
2327
2328 2234 ### Aliases for Columns ### Aliases for Columns
2329 2235
2330 2236 We can use aliases for the columns. We can use aliases for the columns.
 
... ... For nested queries, cf. [@Textbook6, 5.1.2] or [@Textbook7, 7.1.2].
2368 2274
2369 2275 ### Select-Project-Join ### Select-Project-Join
2370 2276
2371 ```
2372 SELECT Login
2373 FROM PROF, DEPARTMENT
2374 WHERE DEPARTMENT.Name = "Mathematics"
2375 AND
2376 Department = Code;
2377 ```
2277 ```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=select-project-join-1}
2278 ```
2378 2279
2379 2280 - `Department.Name = 'Mathematics'` is the selection condition - `Department.Name = 'Mathematics'` is the selection condition
2380 2281 - `Department = Code` is the join condition, because it combines two tuples. - `Department = Code` is the join condition, because it combines two tuples.
2381 2282 - Why do we use the fully qualified name attribute for `Name`? - Why do we use the fully qualified name attribute for `Name`?
2382 2283 - We have to list all the tables we want to consult, even if we use fully qualified names. - We have to list all the tables we want to consult, even if we use fully qualified names.
2383 2284
2384 ```
2385 SELECT Name
2386 FROM STUDENT, GRADE
2387 WHERE Grade > 3.0
2388 AND
2389 STUDENT.Login = GRADE.Login;
2390 ```
2285 ```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=select-project-join-2}
2286 ```
2391 2287
2392 2288 - `Grade > 3.0` is the selection condition - `Grade > 3.0` is the selection condition
2393 2289 - `STUDENT.Login = GRADE.Login` is the join condition - `STUDENT.Login = GRADE.Login` is the join condition
2394 2290
2395 2291 We can have two join conditions! We can have two join conditions!
2396 2292
2397 ```
2398 SELECT PROF.Name
2399 FROM PROF, DEPARTMENT, STUDENT
2400 WHERE STUDENT.Name = "Ava Alyx"
2401 AND
2402 STUDENT.Major = DEPARTMENT.Code
2403 AND
2404 DEPARTMENT.Head = PROF.Login;
2293 ```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=select-project-join-3}
2405 2294 ``` ```
2406 2295
2407 2296 Note that for the kind of join we are studiying (called "inner joins"), the [order does not matter](https://stackoverflow.com/q/9614922). Note that for the kind of join we are studiying (called "inner joins"), the [order does not matter](https://stackoverflow.com/q/9614922).
 
... ... Consider the following example:
2415 2304
2416 2305 We can use aliases on tables to shorten the previous query: We can use aliases on tables to shorten the previous query:
2417 2306
2418 ```
2419 SELECT PROF.Name
2420 FROM PROF, DEPARTMENT, STUDENT AS B
2421 WHERE B.Name = "Ava Alyx"
2422 AND
2423 B.Major = DEPARTMENT.Code
2424 AND
2425 DEPARTMENT.Head = PROF.Login;
2307 ```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=alias-1}
2426 2308 ``` ```
2427 2309
2428 2310 We can use multiple aliases to make it even shorter (but less readable): We can use multiple aliases to make it even shorter (but less readable):
2429 2311
2430 ```
2431 SELECT A.Name
2432 FROM PROF AS A, DEPARTMENT AS B, STUDENT AS C
2433 WHERE C.Name = "Ava Alyx"
2434 AND
2435 C.Major = B.Code
2436 AND
2437 B.Head = A.Login;
2312 ```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=alias-2}
2438 2313 ``` ```
2439 2314
2440 2315 For those two, aliases are convenient, but not required to write the query. For those two, aliases are convenient, but not required to write the query.
2441 2316 In some cases, we cannot do without aliases. In some cases, we cannot do without aliases.
2442 2317 For instance if we want to compare two rows in the same table: For instance if we want to compare two rows in the same table:
2443 2318
2444 ```
2445 SELECT Others.Login
2446 FROM GRADE AS Mine, GRADE AS Others
2447 WHERE Mine.Login = "aalyx"
2448 AND
2449 Mine.Grade < Others.Grade;
2319 ```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=alias-3}
2450 2320 ``` ```
2451 2321
2452 2322 Generally, when you want to perform a join _within the same table_, then you have to "make two copies of the tables" and name them differently using aliases. Generally, when you want to perform a join _within the same table_, then you have to "make two copies of the tables" and name them differently using aliases.
 
... ... Let us try to write a query that answers the question
2457 2327 We need a way of distinguising between the professors we are projecting on (the one whole login is caubert) and the one we are joining with (the ones that have the same department). We need a way of distinguising between the professors we are projecting on (the one whole login is caubert) and the one we are joining with (the ones that have the same department).
2458 2328 This can be done using something like: This can be done using something like:
2459 2329
2460 ```
2461 SELECT JOINT.Login
2462 FROM PROF AS PROJECT, PROF AS JOINT
2463 WHERE PROJECT.Login = "caubert"
2464 AND
2465 PROJECT.Department = JOINT.Department;
2330 ```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=alias-4}
2466 2331 ``` ```
2467 2332
2468 2333 Note that we are "opening up two copies of the PROF tables", and naming them differently (`PROJECT` and `JOINT`). Note that we are "opening up two copies of the PROF tables", and naming them differently (`PROJECT` and `JOINT`).
 
... ... Note that we are "opening up two copies of the PROF tables", and naming them dif
2471 2336
2472 2337 Another (improved) example of a similar query is Another (improved) example of a similar query is
2473 2338
2474 ```
2475 SELECT Fellow.Name AS "Fellow of Ava"
2476 FROM STUDENT AS Ava, STUDENT AS Fellow
2477 WHERE Ava.Name = "Ava Alyx"
2478 AND
2479 Fellow.Major = Ava.Major
2480 AND
2481 NOT Fellow.Login = Ava.Login;
2339 ```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=alias-5}
2482 2340 ``` ```
2483 2341
2484 2342 A couple of remarks about this query: A couple of remarks about this query:
 
... ... A couple of remarks about this query:
2492 2350
2493 2351 Let us look at a first example Let us look at a first example
2494 2352
2495 ```
2496 SELECT Login FROM GRADE
2497 WHERE Grade >
2498 (SELECT AVG(Grade) FROM GRADE);
2353 ```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=nested-1}
2499 2354 ``` ```
2500 2355
2501 2356 A nested query is made of an outer query (`SELECT Login`…) and an inner query (`SELECT AVG(Grade)`…). A nested query is made of an outer query (`SELECT Login`…) and an inner query (`SELECT AVG(Grade)`…).
 
... ... To learn more about those operators, refer to <https://www.w3schools.com/sql/sql
2506 2361
2507 2362 An example could be An example could be
2508 2363
2509 ```
2510 SELECT Login FROM GRADE
2511 WHERE Grade >=
2512 ALL (SELECT Grade FROM GRADE WHERE Grade IS NOT NULL);
2364 ```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=nested-2}
2513 2365 ``` ```
2514 2366
2515 2367 Note that Note that
 
... ... Note that
2518 2370 - The part `IS NOT NULL` is needed: otherwise, if one of the grade is `NULL`, then the comparison would yelds "unknown", and no grade would be greater than all of the others. - The part `IS NOT NULL` is needed: otherwise, if one of the grade is `NULL`, then the comparison would yelds "unknown", and no grade would be greater than all of the others.
2519 2371 - This query could be simplified, using `MAX`: - This query could be simplified, using `MAX`:
2520 2372
2521 ```
2522 SELECT Login FROM GRADE
2523 WHERE Grade >=
2524 (SELECT MAX(Grade) FROM GRADE);
2373 ```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=max}
2525 2374 ``` ```
2526 2375
2527 2376 Answering the question Answering the question
 
... ... Answering the question
2530 2379
2531 2380 --that sounds like the what would ask a police officer in a whodunit-- could be answer using --that sounds like the what would ask a police officer in a whodunit-- could be answer using
2532 2381
2533 ```
2534 SELECT Login
2535 FROM PROF
2536 WHERE DEPARTMENT IN ( SELECT Major
2537 FROM STUDENT
2538 WHERE Login LIKE '%a');
2382 ```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=whodunit}
2539 2383 ``` ```
2540 2384
2541 2385 For this query, we could not use `=`, since more than one major could be returned. For this query, we could not use `=`, since more than one major could be returned.
 
... ... For this query, we could not use `=`, since more than one major could be returne
2543 2387 Furthermore, nested query that uses `=` can often be rewritten without being nested. Furthermore, nested query that uses `=` can often be rewritten without being nested.
2544 2388 For instance, For instance,
2545 2389
2546 ```
2547 SELECT Login
2548 FROM PROF
2549 WHERE DEPARTMENT = ( SELECT Major
2550 FROM STUDENT
2551 WHERE Login = "cjoella");
2390 ```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=transf-1a}
2552 2391 ``` ```
2553 2392
2554 2393 becomes becomes
2555 2394
2556 ```
2557 SELECT PROF.Login
2558 FROM PROF, STUDENT
2559 WHERE DEPARTMENT = Major AND STUDENT.Login = "cjoella";
2395 ```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=transf-1b}
2560 2396 ``` ```
2561 2397
2562 2398 Conversly, you can sometimes write select-project-join as nested queries Conversly, you can sometimes write select-project-join as nested queries
2563 2399 For instance, For instance,
2564 2400
2565 ```
2566 SELECT Name
2567 FROM STUDENT, GRADE
2568 WHERE Grade > 3.0
2569 AND
2570 STUDENT.Login = GRADE.Login;
2401
2402 ```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=transf-2a}
2571 2403 ``` ```
2572 2404
2573 2405 becomes becomes
2574 2406
2407
2408 ```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=transf-2b}
2575 2409 ``` ```
2576 SELECT Name FROM STUDENT
2577 WHERE Login IN (SELECT Login FROM GRADE WHERE Grade > 3.0);
2410
2411 ## Procedures
2412
2413 A "stored" procedure is a `SQL` function statements that can take arguments and may be called from another part of your program.
2414 Stated differently, a procedure is a serie of statements stored in a schema, that can easily be executed repeatedly, cf. <https://dev.mysql.com/doc/refman/8.0/en/create-procedure.html> or <https://mariadb.com/kb/en/library/create-procedure/>.
2415
2416 Imagine we have the following:
2417
2418 ```{.sqlmysql .numberLines include=code/sql/HW_ProcedureExamples.sql snippet=procedure-1}
2578 2419 ``` ```
2579 2420
2421 `SQL` is extremely litteral: when it reads the delimiter `;`, it _must_ execute the command that was shared.
2422 But a procedure, being composed of commands, will contain the `;` symbol.
2423 To "solve" this (weird) issue, and be able to define a procedure, we have to "temporarily alter the language", using `DELIMITER //` that makes the delimiter being `//` instead of `;`[^note-on-delimiter].
2580 2424
2581 ## Procedures
2425 [^note-on-delimiter]:
2426 The symbols `$$` are often used too, and the documentation, at <https://dev.mysql.com/doc/refman/8.0/en/stored-programs-defining.html>, reads:
2582 2427
2583 A "stored" procedure is a series of `SQL` statements that can be "called" from another part of your program.
2584 It is pretty much like defining a function, and, exactly like a function, it can takes arguments.
2585 In MariaDB, you could have the following program.
2428 > You can redefine the delimiter to a string other than `//` and the delimiter can consist of a single character or multiple characters. You should avoid the use of the backslash (`\`) character because that is the escape character for MySQL.
2586 2429
2430 The minus sign twice is also a poor choice, since it is used for commenting.
2587 2431
2588 ```{.sqlmysql .numberLines include=code/sql/HW_ProcedureExamples.sql}
2432 In any case, we can then define and execute a simpe procedure called `STUDENTLIST` as follows:
2433
2434 ```{.sqlmysql .numberLines include=code/sql/HW_ProcedureExamples.sql snippet=procedure-2}
2435 ```
2436
2437 A procedure an also take arguments, and an example could be:
2438
2439
2440 ```{.sqlmysql .numberLines include=code/sql/HW_ProcedureExamples.sql snippet=procedure-3}
2589 2441 ``` ```
2590 2442
2591 2443 ## Triggers ## Triggers
 
... ... A trigger is a series of statements stored in a schema that can be automatically
2594 2446 Triggers are extremely powerfull, and are a way of automating part of the work in your database. Triggers are extremely powerfull, and are a way of automating part of the work in your database.
2595 2447 In MariaDB, you could have the following program. In MariaDB, you could have the following program.
2596 2448
2449 Imagine we have the following:
2450
2451 ```{.sqlmysql .numberLines include=code/sql/HW_TriggerExample.sql snippet=trigger-1}
2452 ```
2453
2454 We want to create a trigger that counts the number of times something was inserted in our `STUDENT` table.
2455 `SQL` supports some primitive form of variables (cf. <https://dev.mysql.com/doc/refman/8.0/en/user-variables.html> and <https://mariadb.com/kb/en/library/user-defined-variables/>).
2456 There is no "clear" form of type, <https://dev.mysql.com/doc/refman/8.0/en/user-variables.html> reads:
2457
2458 > In addition, the default result type of a variable is based on its type at the beginning of the statement. This may have unintended effects if a variable holds a value of one type at the beginning of a
2459 statement in which it is also assigned a new value of a different type. To avoid problems with this behavior, either do not assign a value to and read the value of the same variable within a single statement, or else set the variable to 0, 0.0, or '' to define its type before you use it.
2460
2461 In other words, `SQL` just "guess" the type of your value and go with it.
2462 Creating a simple trigger that increment a variable every time an insertion is performed in the `STUDENT` table can be done as follows:
2463
2464 ```{.sqlmysql .numberLines include=code/sql/HW_TriggerExample.sql snippet=trigger-2}
2465 ```
2466
2467 Now, assume we want to create a trigger that calculates the average for us.
2468 Note that the trigger will need to manipulate two tables (`STUDENT` and `GRADE`) at the same time.
2597 2469
2598 ```{.sqlmysql .numberLines include=code/sql/HW_TriggerExample.sql}
2470 ```{.sqlmysql .numberLines include=code/sql/HW_TriggerExample.sql snippet=trigger-3}
2599 2471 ``` ```
2600 2472
2473 The source code contains examples of insertion and explanations on how to witness the trigger in action.
2601 2474
2602 2475 ## Setting Up Your Work Environment {#sec:setup} ## Setting Up Your Work Environment {#sec:setup}
2603 2476
 
... ... The following links could be useful:
2645 2518 #. Save the "mysql-installer-web-community-XXX.msi" file, and open it. If there is an updated version of the installer available, agree to download it. Accept the license term. #. Save the "mysql-installer-web-community-XXX.msi" file, and open it. If there is an updated version of the installer available, agree to download it. Accept the license term.
2646 2519 #. We will now install the various components needed for this class, leaving all the choices by defaults. This means that you need to do the following: #. We will now install the various components needed for this class, leaving all the choices by defaults. This means that you need to do the following:
2647 2520 #. Leave the first option on "Developer Default" and click on "Next", or click on "Custom", and select the following: #. Leave the first option on "Developer Default" and click on "Next", or click on "Custom", and select the following:
2648
2649 ![mysql Installation](img/mysql_install.png){width=90%}
2650
2521 ![mysql Installation](img/mysql_install.png){width=90%}\
2651 2522 #. Click on "Next" even if you do not meet all the requirements #. Click on "Next" even if you do not meet all the requirements
2652 2523 #. Click on "Execute". The system will download and install several softwares (this may take some time). #. Click on "Execute". The system will download and install several softwares (this may take some time).
2653 2524 #. Click on "Next" twice, leave "Type and Networking" on "Standalone MySQL Server / Classic MySQL Replication" and click "Next", and leave the next options as they are (unless you know what you do and want to change the port, for instance) and click on "Next". #. Click on "Next" twice, leave "Type and Networking" on "Standalone MySQL Server / Classic MySQL Replication" and click "Next", and leave the next options as they are (unless you know what you do and want to change the port, for instance) and click on "Next".
 
... ... Exercise +.#
2977 2848
2978 2849 Data type | Examples | Data type | Examples |
2979 2850 --- | --- | --- | --- |
2980 | `4`, `-32`
2851   | `4`, `-32`
2981 2852 Char(4) |   Char(4) |  
2982 2853 VarChar(10) | `'Train'`, `'Michelle'` VarChar(10) | `'Train'`, `'Michelle'`
2983 2854 Bit(4) |   Bit(4) |  
2984 | `TRUE`, `UNKNOWN`
2855   | `TRUE`, `UNKNOWN`
2985 2856
2986 2857 Exercise +.#sqldatatype Exercise +.#sqldatatype
2987 2858
 
... ... Solution +.#
3234 3105
3235 3106 Data type | Examples Data type | Examples
3236 3107 --- | --- --- | ---
3237 Int | `4`, `-32`
3238 Char(4) | `'trai'`, `'plol'`
3239 VarChar(10) | `'Train'`, `'Michelle'`
3240 Bit(4) | `B'1010'`, `B'0101'`
3241 Boolean | `TRUE`, `UNKNOWN`
3108 `INT` | `4`, `-32`
3109 `CHAR(4)` | `'abCD'`, `"dEfG"`
3110 `VARCHAR(10)` | `'Train'`, `'Michelle'`
3111 `BIT(4)` | `B'1010'`, `B'0101'`
3112 `BOOL`` | `TRUE`, `FALSE`, `NULL`
3113
3114 `NULL` is actually a valid answer for every single type of
3242 3115
3243 3116 Solution +.# Solution +.#
3244 3117
 
... ... Solution +.#
3252 3125 ~ ~
3253 3126 A simple and compact code could be: A simple and compact code could be:
3254 3127
3255 ```
3256 -- You can ignore the first three lines.
3257 DROP SCHEMA IF EXISTS HW_SHORT;
3258 CREATE SCHEMA HW_SHORT;
3259 USE HW_SHORT;
3260 CREATE TABLE A(Att1 INT PRIMARY KEY, Att2 INT);
3261 CREATE TABLE B(Att3 INT PRIMARY KEY, Att4 INT, FOREIGN KEY (Att4) REFERENCES A(Att1));
3262 INSERT INTO A VALUES (1, 2);
3263 INSERT INTO B VALUES (3, 1);
3128 ```{.sqlmysql .numberLines include=code/sql/HW_Short.sql snippet=solution}
3264 3129 ``` ```
3265 3130
3266 3131 Solution +.# Solution +.#
 
... ... Problem (Constraints on foreign keys) +.#fk
3652 3517 Problem (Revisiting the PROF table) +.#profrevisited Problem (Revisiting the PROF table) +.#profrevisited
3653 3518 ~ ~
3654 3519
3655 Create the `PROF`, `STUDENT`, `DEPARTMENT` and `GRADE` tables as in the ["Constructing and populating a new example"](#sec:profexample) section.
3520 Create the `PROF`, `DEPARTMENT`, `STUDENT` and `GRADE` tables as in the ["Constructing and populating a new example"](#sec:profexample) section.
3656 3521 Populate them with some data (copy it from the notes or come up with your own data). Populate them with some data (copy it from the notes or come up with your own data).
3657 3522
3658 3523 @problem:profrevisited -- Question -.# @problem:profrevisited -- Question -.#
 
... ... Problem (Read, correct, and write `SQL` statements for the COFFEE database) +.#c
3826 3691 #. Every statement respects `SQL`'s syntax (there's no "a semi-colon is missing" trap). #. Every statement respects `SQL`'s syntax (there's no "a semi-colon is missing" trap).
3827 3692 #. None of these commands are actually executed; the data is always in the state depicted above. #. None of these commands are actually executed; the data is always in the state depicted above.
3828 3693
3829 You can use **COFFEE**.1 to denote the first tuple (or row) in **COFFEE**, and similarly for other relations and tuples (so that, for instance, **SUPPLY**.$4$ corresponds to `"Johns & Co"., 221`).
3694 You can use **COFFEE**.1 to denote the first tuple (or row) in **COFFEE**, and similarly for other relations and tuples (so that, for instance, **SUPPLY**.$4$ corresponds to `"Johns & Co"., 221`).
3830 3695
3831 3696 @problem:coffee -- Question -.# @problem:coffee -- Question -.#
3832 3697
 
... ... Solution to [%D %n (%T)](#problem:fk)
4554 4419
4555 4420 Solution to [%D %n (%T)](#problem:profrevisited) Solution to [%D %n (%T)](#problem:profrevisited)
4556 4421 ~ ~
4422
4557 4423
4558 For Questions 1 and 5, we should have:
4424 @problem:profrevisited-- Solution to Q. -.#
4425 ~
4426
4427 Ignoring the LECTURE relation, we have:
4559 4428
4560 4429 ![PROF(Login (PK), Name, Department (FK to DEPARTMENT.Code)) ![PROF(Login (PK), Name, Department (FK to DEPARTMENT.Code))
4561 4430 DEPARTMENT(Code (PK), Name, Head (FK to PROF.Login)) DEPARTMENT(Code (PK), Name, Head (FK to PROF.Login))
 
... ... Solution to [%D %n (%T)](#problem:profrevisited)
4565 4434 ](fig/rel_mod/professor_department_extended) ](fig/rel_mod/professor_department_extended)
4566 4435 \ \
4567 4436
4437 @problem:profrevisited-- Solution to Q. -.#
4438 ~
4439
4440
4568 4441 For the other questions, refer to this code. For the other questions, refer to this code.
4569 4442
4570 4443 ```{.sqlmysql .numberLines include=code/sql/HW_Lecture.sql} ```{.sqlmysql .numberLines include=code/sql/HW_Lecture.sql}
File notes/style/style.css changed (mode: 100644) (index ce21726..d020f1a)
... ... a, div, label, p, img, span, section, h2, h3, li, pre {
29 29 .sourceCode { .sourceCode {
30 30 text-indent: 0; text-indent: 0;
31 31 word-wrap: break-word; word-wrap: break-word;
32 overflow: hidden;
33 32 resize: horizontal; resize: horizontal;
34 33 } }
35 34
35 /*
36 36 .sourceCode:after { .sourceCode:after {
37 37 content: attr(data-caption); content: attr(data-caption);
38 38 font-weight: bold; font-weight: bold;
39 39 } }
40 */
40 41
41 42 a.sourceLine::before { a.sourceLine::before {
42 43 text-decoration: none; text-decoration: none;
File notes/temp.md changed (mode: 100644) (index 2f2b203..12d324a)
1
1 2 --- ---
2 3 documentclass: scrreprt documentclass: scrreprt
3 4 title: CSCI 3410 - Database Systems title: CSCI 3410 - Database Systems
 
... ... pandoc-numbering:
32 33 format-link-title: 'Pb %n' format-link-title: 'Pb %n'
33 34 --- ---
34 35
35
36 | A | B|
37 | --- | ---------- |
38 | A long, long, long, long, long, long, text. | A long, long, long, long, long, long, text. |
36 ```{.numberLines}
37 this is a very long long long long long long long long long long long long long line which is broken. this is a very long long long long long long long long long long long long long line which is broken. this is a very long long long long long long long long long long long long long line which is broken.
38 this is a very long long long long long long long long long long long long long line which is broken. this is a very long long long long long long long long long long long long long line which is broken. this is a very long long long long long long long long long long long long long line which is broken.
39
40 ```
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/caubert/CSCI_3410

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/caubert/CSCI_3410

Clone this repository using git:
git clone git://git.rocketgit.com/user/caubert/CSCI_3410

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main