File notes/lectures_notes.md changed (mode: 100644) (index 219e9c2..ee220af) |
... |
... |
pandoc-numbering: |
30 |
30 |
latex: |
latex: |
31 |
31 |
format-link-classic: 'Pb %n' |
format-link-classic: 'Pb %n' |
32 |
32 |
format-link-title: 'Pb %n' |
format-link-title: 'Pb %n' |
|
33 |
|
base: https://rocketgit.com/user/caubert/CSCI_3410/source/tree/branch/master/blob/notes/ |
33 |
34 |
--- |
--- |
34 |
35 |
|
|
35 |
36 |
# Preamble {-} |
# Preamble {-} |
|
... |
... |
Reading them before coming to the lecture will help you getting a sense of the n |
42 |
43 |
|
|
43 |
44 |
When it comes to code, you can normally copy-and-paste it from the document and use it as it is. |
When it comes to code, you can normally copy-and-paste it from the document and use it as it is. |
44 |
45 |
Or, you can browse the source code of the code snippets at <https://rocketgit.com/user/caubert/CSCI_3410/source/tree/branch/master/tree/notes/code> to download it directly. |
Or, you can browse the source code of the code snippets at <https://rocketgit.com/user/caubert/CSCI_3410/source/tree/branch/master/tree/notes/code> to download it directly. |
45 |
|
Some portion of code starts with a path in comment, like so: |
|
|
46 |
|
Some portion of code starts with a path in comment, and are followed by a link, like so: |
46 |
47 |
|
|
47 |
48 |
|
|
48 |
|
```{.sqlmysql .numberLines include=code/sql/HW_HelloWorld.sql} |
|
|
49 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_HelloWorld.sql} |
49 |
50 |
``` |
``` |
50 |
51 |
|
|
51 |
|
This means that this code can be found at [https://rocketgit.com/user/caubert/CSCI_3410/source/tree/branch/master/**blob/notes/code/sql/HW_HelloWorld.sql**](https://rocketgit.com/user/caubert/CSCI_3410/source/tree/branch/master/blob/notes/code/sql/HW_HelloWorld.sql). |
|
|
52 |
|
This means that this code can be found at [https://rocketgit.com/user/caubert/CSCI_3410/source/tree/branch/master/**blob/notes/code/sql/HW_HelloWorld.sql**](https://rocketgit.com/user/caubert/CSCI_3410/source/tree/branch/master/blob/notes/code/sql/HW_HelloWorld.sql), and that you can click the link directly to access it^[This feature was [actually implemented by a student!](https://github.com/owickstrom/pandoc-include-code/pull/36).]. |
52 |
53 |
|
|
53 |
54 |
The `SQL` code frequently starts with |
The `SQL` code frequently starts with |
54 |
55 |
|
|
|
... |
... |
On top of the notes, you will find in this document: |
76 |
77 |
- A list of short exercises, |
- A list of short exercises, |
77 |
78 |
- Solution to those exercises, - A list of problem, - Sometimes, solution to some of those problems. Any feedback is greatly appreciated. Please refer to <https://spots.augusta.edu/caubert/db/ln/README.html#contributing> for how to contribute to those notes. The syllabus is at <https://spots.augusta.edu/caubert/db/>, and the webpage for this notes is at <https://spots.augusta.edu/caubert/db/ln/>. Please, refer to those notes using this entry [@AubertCSCI3410-DatabaseSystems]: |
- Solution to those exercises, - A list of problem, - Sometimes, solution to some of those problems. Any feedback is greatly appreciated. Please refer to <https://spots.augusta.edu/caubert/db/ln/README.html#contributing> for how to contribute to those notes. The syllabus is at <https://spots.augusta.edu/caubert/db/>, and the webpage for this notes is at <https://spots.augusta.edu/caubert/db/ln/>. Please, refer to those notes using this entry [@AubertCSCI3410-DatabaseSystems]: |
78 |
79 |
|
|
79 |
|
```{.bibtex include=bib/entry.bib} |
|
80 |
|
``` |
|
|
80 |
|
```{.bibtex .includeLink include=bib/entry.bib} |
|
81 |
|
``` |
81 |
82 |
|
|
82 |
83 |
## Planned Schedule {-} |
## Planned Schedule {-} |
83 |
84 |
|
|
|
... |
... |
There are many other datatypes, but they really depends on the particular implem |
1531 |
1532 |
## First Commands |
## First Commands |
1532 |
1533 |
|
|
1533 |
1534 |
|
|
1534 |
|
```{.sqlmysql .numberLines include=code/sql/HW_Faculty.sql} |
|
|
1535 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_Faculty.sql} |
1535 |
1536 |
``` |
``` |
1536 |
1537 |
|
|
1537 |
1538 |
## Useful Commands |
## Useful Commands |
|
... |
... |
For more in-depth examples, you can refer to <https://www.w3resource.com/mysql/c |
1610 |
1611 |
We will now see how to declare those constraints when we create the table (except for the foreign key, which we save for later). |
We will now see how to declare those constraints when we create the table (except for the foreign key, which we save for later). |
1611 |
1612 |
|
|
1612 |
1613 |
|
|
1613 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ConstraintsPart1.sql} |
|
|
1614 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ConstraintsPart1.sql} |
1614 |
1615 |
``` |
``` |
1615 |
1616 |
|
|
1616 |
1617 |
If we wanted to combine multiple constraints, we would have to follow the order described at <https://dev.mysql.com/doc/refman/8.0/en/create-table.html>. |
If we wanted to combine multiple constraints, we would have to follow the order described at <https://dev.mysql.com/doc/refman/8.0/en/create-table.html>. |
|
... |
... |
MariaDB [HW_ConstraintsPart1]> DESCRIBE STATE; |
1640 |
1641 |
|
|
1641 |
1642 |
Note that more than one attribute can be the primary key, in which case the syntax needs to be something like the following: |
Note that more than one attribute can be the primary key, in which case the syntax needs to be something like the following: |
1642 |
1643 |
|
|
1643 |
|
```{.sqlmysql .numberLines include=code/sql/HW_PKtest.sql} |
|
|
1644 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_PKtest.sql} |
1644 |
1645 |
``` |
``` |
1645 |
1646 |
|
|
1646 |
1647 |
Note that in this case, a statement like |
Note that in this case, a statement like |
|
... |
... |
INSERT INTO HURRICANE VALUES ("Test2", DEFAULT, NULL); |
1678 |
1679 |
Note that, by default, the `DEFAULT` value is `NULL`, regardless of the datatype: |
Note that, by default, the `DEFAULT` value is `NULL`, regardless of the datatype: |
1679 |
1680 |
|
|
1680 |
1681 |
|
|
1681 |
|
```{.sqlmysql .numberLines include=code/sql/HW_DefaultTest.sql} |
|
|
1682 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_DefaultTest.sql} |
1682 |
1683 |
``` |
``` |
1683 |
1684 |
|
|
1684 |
1685 |
### Editing Constraints |
### Editing Constraints |
|
... |
... |
In the example below, we introduce the foreign key update and delete rules. |
1825 |
1826 |
We also introduce, passing by, the enumerated data type, and how to edit it. |
We also introduce, passing by, the enumerated data type, and how to edit it. |
1826 |
1827 |
|
|
1827 |
1828 |
|
|
1828 |
|
```{.sqlmysql .numberLines include=code/sql/HW_Storm.sql snippet=schema} |
|
|
1829 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_Storm.sql snippet=schema} |
1829 |
1830 |
``` |
``` |
1830 |
1831 |
|
|
1831 |
1832 |
Note that we can "inline" the foreign key constraint like we "inlined" the primary key constraint (cf. <https://stackoverflow.com/q/24313143/>), but that **it will not be enforced**! |
Note that we can "inline" the foreign key constraint like we "inlined" the primary key constraint (cf. <https://stackoverflow.com/q/24313143/>), but that **it will not be enforced**! |
|
... |
... |
Note that we can "inline" the foreign key constraint like we "inlined" the prima |
1833 |
1834 |
|
|
1834 |
1835 |
Let us now illustrate this table by introducing some data in it: |
Let us now illustrate this table by introducing some data in it: |
1835 |
1836 |
|
|
1836 |
|
```{.sqlmysql .numberLines include=code/sql/HW_Storm.sql snippet=insert} |
|
|
1837 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_Storm.sql snippet=insert} |
1837 |
1838 |
``` |
``` |
1838 |
1839 |
|
|
1839 |
1840 |
MySQL will always notify you if there is an error in a date attribute when you use the `DATE` prefix. |
MySQL will always notify you if there is an error in a date attribute when you use the `DATE` prefix. |
1840 |
1841 |
|
|
1841 |
|
```{.sqlmysql .numberLines include=code/sql/HW_Storm.sql snippet=date} |
|
|
1842 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_Storm.sql snippet=date} |
1842 |
1843 |
``` |
``` |
1843 |
1844 |
|
|
1844 |
1845 |
We will see in the ["Reverse-Engineering"](#reverse-engineering-1) section why this schema is poorly designed, but for now, let's focus on the foreign keys and their restrictions. |
We will see in the ["Reverse-Engineering"](#reverse-engineering-1) section why this schema is poorly designed, but for now, let's focus on the foreign keys and their restrictions. |
|
... |
... |
DEPARTMENT(Code (PK), Name, Head (FK to PROF.Login)) |
1995 |
1996 |
\ |
\ |
1996 |
1997 |
|
|
1997 |
1998 |
|
|
1998 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=tables-1} |
|
|
1999 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ProfExample.sql snippet=tables-1} |
1999 |
2000 |
``` |
``` |
2000 |
2001 |
|
|
2001 |
2002 |
Note the structure of the `ALTER TABLE` command: |
Note the structure of the `ALTER TABLE` command: |
|
... |
... |
Note the structure of the `ALTER TABLE` command: |
2004 |
2005 |
- … `KEY (Department) REFERENCES (Code);`⇒ error |
- … `KEY (Department) REFERENCES (Code);`⇒ error |
2005 |
2006 |
- … `KEY PROF(Department) REFERENCES DEPARTMENT(Code);` ⇒ ok |
- … `KEY PROF(Department) REFERENCES DEPARTMENT(Code);` ⇒ ok |
2006 |
2007 |
|
|
2007 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=tables-2} |
|
|
2008 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ProfExample.sql snippet=tables-2} |
2008 |
2009 |
``` |
``` |
2009 |
2010 |
|
|
2010 |
2011 |
#### Populating |
#### Populating |
2011 |
2012 |
|
|
2012 |
2013 |
We can insert multiple values at once: |
We can insert multiple values at once: |
2013 |
2014 |
|
|
2014 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=insert-1} |
|
|
2015 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ProfExample.sql snippet=insert-1} |
2015 |
2016 |
``` |
``` |
2016 |
2017 |
|
|
2017 |
2018 |
We can specify which attributes we are giving: |
We can specify which attributes we are giving: |
2018 |
2019 |
|
|
2019 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=insert-2} |
|
|
2020 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ProfExample.sql snippet=insert-2} |
2020 |
2021 |
``` |
``` |
2021 |
2022 |
|
|
2022 |
2023 |
And we can even specify the order (even the trivial one): |
And we can even specify the order (even the trivial one): |
2023 |
2024 |
|
|
2024 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=insert-3} |
|
|
2025 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ProfExample.sql snippet=insert-3} |
2025 |
2026 |
``` |
``` |
2026 |
2027 |
|
|
2027 |
2028 |
Note the date literals. |
Note the date literals. |
|
... |
... |
Note the date literals. |
2030 |
2031 |
|
|
2031 |
2032 |
Note that we can create foreign keys to primary keys made of multiple attributes, and to the primary key of the table we are currently creating. |
Note that we can create foreign keys to primary keys made of multiple attributes, and to the primary key of the table we are currently creating. |
2032 |
2033 |
|
|
2033 |
|
```{.sqlmysql .numberLines include=code/sql/HW_AdvancedFK.sql snippet=advancedFK} |
|
|
2034 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_AdvancedFK.sql snippet=advancedFK} |
2034 |
2035 |
``` |
``` |
2035 |
2036 |
|
|
2036 |
2037 |
## A First Look at Conditions |
## A First Look at Conditions |
|
... |
... |
Conditions can |
2075 |
2076 |
- `_` will match one character (any character), `%` will match any number of character, |
- `_` will match one character (any character), `%` will match any number of character, |
2076 |
2077 |
- advanced regular expression possible using the `REGEXP` keyword. |
- advanced regular expression possible using the `REGEXP` keyword. |
2077 |
2078 |
|
|
2078 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=select-update} |
|
|
2079 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ProfExample.sql snippet=select-update} |
2079 |
2080 |
``` |
``` |
2080 |
2081 |
|
|
2081 |
2082 |
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). |
|
... |
... |
U | U |
2141 |
2142 |
|
|
2142 |
2143 |
You can test if a value is `NULL` with `IS NULL`. |
You can test if a value is `NULL` with `IS NULL`. |
2143 |
2144 |
|
|
2144 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=null} |
|
|
2145 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ProfExample.sql snippet=null} |
2145 |
2146 |
``` |
``` |
2146 |
2147 |
|
|
2147 |
2148 |
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. |
|
... |
... |
There is also `INTERSECT` and `EXCEPT` in the specification, but MySQL does not |
2229 |
2230 |
|
|
2230 |
2231 |
You can have `ORDER BY` specifications: |
You can have `ORDER BY` specifications: |
2231 |
2232 |
|
|
2232 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=order-by} |
|
|
2233 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ProfExample.sql snippet=order-by} |
2233 |
2234 |
``` |
``` |
2234 |
2235 |
|
|
2235 |
2236 |
`ORDER BY` order by ascending order by default. |
`ORDER BY` order by ascending order by default. |
|
... |
... |
returns the number of _different names_ (which in this case is the same as the n |
2258 |
2259 |
|
|
2259 |
2260 |
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: |
2260 |
2261 |
|
|
2261 |
|
```{.sqlmysql .numberLines include=code/sql/HW_Avg.sql snippet=show-avg} |
|
|
2262 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_Avg.sql snippet=show-avg} |
2262 |
2263 |
``` |
``` |
2263 |
2264 |
|
|
2264 |
2265 |
The same goes for e.g. MAX: |
The same goes for e.g. MAX: |
2265 |
2266 |
|
|
2266 |
|
```{.sqlmysql .numberLines include=code/sql/HW_Max.sql snippet=show-max} |
|
|
2267 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_Max.sql snippet=show-max} |
2267 |
2268 |
``` |
``` |
2268 |
2269 |
|
|
2269 |
2270 |
|
|
|
... |
... |
For nested queries, cf. [@Textbook6, 5.1.2] or [@Textbook7, 7.1.2]. |
2310 |
2311 |
|
|
2311 |
2312 |
### Select-Project-Join |
### Select-Project-Join |
2312 |
2313 |
|
|
2313 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=select-project-join-1} |
|
|
2314 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ProfExample.sql snippet=select-project-join-1} |
2314 |
2315 |
``` |
``` |
2315 |
2316 |
|
|
2316 |
2317 |
- `Department.Name = 'Mathematics'` is the selection condition |
- `Department.Name = 'Mathematics'` is the selection condition |
|
... |
... |
For nested queries, cf. [@Textbook6, 5.1.2] or [@Textbook7, 7.1.2]. |
2318 |
2319 |
- Why do we use the fully qualified name attribute for `Name`? |
- Why do we use the fully qualified name attribute for `Name`? |
2319 |
2320 |
- 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. |
2320 |
2321 |
|
|
2321 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=select-project-join-2} |
|
|
2322 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ProfExample.sql snippet=select-project-join-2} |
2322 |
2323 |
``` |
``` |
2323 |
2324 |
|
|
2324 |
2325 |
- `Grade > 3.0` is the selection condition |
- `Grade > 3.0` is the selection condition |
|
... |
... |
For nested queries, cf. [@Textbook6, 5.1.2] or [@Textbook7, 7.1.2]. |
2326 |
2327 |
|
|
2327 |
2328 |
We can have two join conditions! |
We can have two join conditions! |
2328 |
2329 |
|
|
2329 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=select-project-join-3} |
|
|
2330 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ProfExample.sql snippet=select-project-join-3} |
2330 |
2331 |
``` |
``` |
2331 |
2332 |
|
|
2332 |
2333 |
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: |
2340 |
2341 |
|
|
2341 |
2342 |
We can use aliases on tables to shorten the previous query: |
We can use aliases on tables to shorten the previous query: |
2342 |
2343 |
|
|
2343 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=alias-1} |
|
|
2344 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ProfExample.sql snippet=alias-1} |
2344 |
2345 |
``` |
``` |
2345 |
2346 |
|
|
2346 |
2347 |
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): |
2347 |
2348 |
|
|
2348 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=alias-2} |
|
|
2349 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ProfExample.sql snippet=alias-2} |
2349 |
2350 |
``` |
``` |
2350 |
2351 |
|
|
2351 |
2352 |
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. |
2352 |
2353 |
In some cases, we cannot do without aliases. |
In some cases, we cannot do without aliases. |
2353 |
2354 |
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: |
2354 |
2355 |
|
|
2355 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=alias-3} |
|
|
2356 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ProfExample.sql snippet=alias-3} |
2356 |
2357 |
``` |
``` |
2357 |
2358 |
|
|
2358 |
2359 |
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 |
2363 |
2364 |
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). |
2364 |
2365 |
This can be done using something like: |
This can be done using something like: |
2365 |
2366 |
|
|
2366 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=alias-4} |
|
|
2367 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ProfExample.sql snippet=alias-4} |
2367 |
2368 |
``` |
``` |
2368 |
2369 |
|
|
2369 |
2370 |
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 |
2372 |
2373 |
|
|
2373 |
2374 |
Another (improved) example of a similar query is |
Another (improved) example of a similar query is |
2374 |
2375 |
|
|
2375 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=alias-5} |
|
|
2376 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ProfExample.sql snippet=alias-5} |
2376 |
2377 |
``` |
``` |
2377 |
2378 |
|
|
2378 |
2379 |
A couple of remarks about this query: |
A couple of remarks about this query: |
|
... |
... |
A couple of remarks about this query: |
2386 |
2387 |
|
|
2387 |
2388 |
Let us look at a first example |
Let us look at a first example |
2388 |
2389 |
|
|
2389 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=nested-1} |
|
|
2390 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ProfExample.sql snippet=nested-1} |
2390 |
2391 |
``` |
``` |
2391 |
2392 |
|
|
2392 |
2393 |
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 |
2397 |
2398 |
|
|
2398 |
2399 |
An example could be |
An example could be |
2399 |
2400 |
|
|
2400 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=nested-2} |
|
|
2401 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ProfExample.sql snippet=nested-2} |
2401 |
2402 |
``` |
``` |
2402 |
2403 |
|
|
2403 |
2404 |
Note that |
Note that |
|
... |
... |
Note that |
2406 |
2407 |
- 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. |
2407 |
2408 |
- This query could be simplified, using `MAX`: |
- This query could be simplified, using `MAX`: |
2408 |
2409 |
|
|
2409 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=max} |
|
|
2410 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ProfExample.sql snippet=max} |
2410 |
2411 |
``` |
``` |
2411 |
2412 |
|
|
2412 |
2413 |
Answering the question |
Answering the question |
|
... |
... |
Answering the question |
2415 |
2416 |
|
|
2416 |
2417 |
--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 |
2417 |
2418 |
|
|
2418 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=whodunit} |
|
|
2419 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ProfExample.sql snippet=whodunit} |
2419 |
2420 |
``` |
``` |
2420 |
2421 |
|
|
2421 |
2422 |
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 |
2423 |
2424 |
Furthermore, nested query that uses `=` can often be rewritten without being nested. |
Furthermore, nested query that uses `=` can often be rewritten without being nested. |
2424 |
2425 |
For instance, |
For instance, |
2425 |
2426 |
|
|
2426 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=transf-1a} |
|
|
2427 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ProfExample.sql snippet=transf-1a} |
2427 |
2428 |
``` |
``` |
2428 |
2429 |
|
|
2429 |
2430 |
becomes |
becomes |
2430 |
2431 |
|
|
2431 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=transf-1b} |
|
|
2432 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ProfExample.sql snippet=transf-1b} |
2432 |
2433 |
``` |
``` |
2433 |
2434 |
|
|
2434 |
2435 |
Conversly, you can sometimes write select-project-join as nested queries |
Conversly, you can sometimes write select-project-join as nested queries |
2435 |
2436 |
For instance, |
For instance, |
2436 |
2437 |
|
|
2437 |
2438 |
|
|
2438 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=transf-2a} |
|
|
2439 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ProfExample.sql snippet=transf-2a} |
2439 |
2440 |
``` |
``` |
2440 |
2441 |
|
|
2441 |
2442 |
becomes |
becomes |
2442 |
2443 |
|
|
2443 |
2444 |
|
|
2444 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=transf-2b} |
|
|
2445 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ProfExample.sql snippet=transf-2b} |
2445 |
2446 |
``` |
``` |
2446 |
2447 |
|
|
2447 |
2448 |
## Procedures |
## Procedures |
|
... |
... |
Stated differently, a procedure is a serie of statements stored in a schema, tha |
2451 |
2452 |
|
|
2452 |
2453 |
Imagine we have the following: |
Imagine we have the following: |
2453 |
2454 |
|
|
2454 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProcedureExamples.sql snippet=procedure-1} |
|
|
2455 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ProcedureExamples.sql snippet=procedure-1} |
2455 |
2456 |
``` |
``` |
2456 |
2457 |
|
|
2457 |
2458 |
`SQL` is extremely litteral: when it reads the delimiter `;`, it _must_ execute the command that was shared. |
`SQL` is extremely litteral: when it reads the delimiter `;`, it _must_ execute the command that was shared. |
|
... |
... |
To "solve" this (weird) issue, and be able to define a procedure, we have to "te |
2467 |
2468 |
|
|
2468 |
2469 |
In any case, we can then define and execute a simpe procedure called `STUDENTLIST` as follows: |
In any case, we can then define and execute a simpe procedure called `STUDENTLIST` as follows: |
2469 |
2470 |
|
|
2470 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProcedureExamples.sql snippet=procedure-2} |
|
|
2471 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ProcedureExamples.sql snippet=procedure-2} |
2471 |
2472 |
``` |
``` |
2472 |
2473 |
|
|
2473 |
2474 |
A procedure an also take arguments, and an example could be: |
A procedure an also take arguments, and an example could be: |
2474 |
2475 |
|
|
2475 |
2476 |
|
|
2476 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProcedureExamples.sql snippet=procedure-3} |
|
|
2477 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ProcedureExamples.sql snippet=procedure-3} |
2477 |
2478 |
``` |
``` |
2478 |
2479 |
|
|
2479 |
2480 |
## Triggers |
## Triggers |
|
... |
... |
In MariaDB, you could have the following program. |
2484 |
2485 |
|
|
2485 |
2486 |
Imagine we have the following: |
Imagine we have the following: |
2486 |
2487 |
|
|
2487 |
|
```{.sqlmysql .numberLines include=code/sql/HW_TriggerExample.sql snippet=trigger-1} |
|
|
2488 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_TriggerExample.sql snippet=trigger-1} |
2488 |
2489 |
``` |
``` |
2489 |
2490 |
|
|
2490 |
2491 |
We want to create a trigger that counts the number of times something was inserted in our `STUDENT` table. |
We want to create a trigger that counts the number of times something was inserted in our `STUDENT` table. |
|
... |
... |
statement in which it is also assigned a new value of a different type. To avoi |
2497 |
2498 |
In other words, `SQL` just "guess" the type of your value and go with it. |
In other words, `SQL` just "guess" the type of your value and go with it. |
2498 |
2499 |
Creating a simple trigger that increment a variable every time an insertion is performed in the `STUDENT` table can be done as follows: |
Creating a simple trigger that increment a variable every time an insertion is performed in the `STUDENT` table can be done as follows: |
2499 |
2500 |
|
|
2500 |
|
```{.sqlmysql .numberLines include=code/sql/HW_TriggerExample.sql snippet=trigger-2} |
|
|
2501 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_TriggerExample.sql snippet=trigger-2} |
2501 |
2502 |
``` |
``` |
2502 |
2503 |
|
|
2503 |
2504 |
Now, assume we want to create a trigger that calculates the average for us. |
Now, assume we want to create a trigger that calculates the average for us. |
2504 |
2505 |
Note that the trigger will need to manipulate two tables (`STUDENT` and `GRADE`) at the same time. |
Note that the trigger will need to manipulate two tables (`STUDENT` and `GRADE`) at the same time. |
2505 |
2506 |
|
|
2506 |
|
```{.sqlmysql .numberLines include=code/sql/HW_TriggerExample.sql snippet=trigger-3} |
|
|
2507 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_TriggerExample.sql snippet=trigger-3} |
2507 |
2508 |
``` |
``` |
2508 |
2509 |
|
|
2509 |
2510 |
The source code contains examples of insertion and explanations on how to witness the trigger in action. |
The source code contains examples of insertion and explanations on how to witness the trigger in action. |
|
... |
... |
Solution +.# |
3161 |
3162 |
~ |
~ |
3162 |
3163 |
A simple and compact code could be: |
A simple and compact code could be: |
3163 |
3164 |
|
|
3164 |
|
```{.sqlmysql .numberLines include=code/sql/HW_Short.sql snippet=solution} |
|
|
3165 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_Short.sql snippet=solution} |
3165 |
3166 |
``` |
``` |
3166 |
3167 |
|
|
3167 |
3168 |
Solution +.# |
Solution +.# |
|
... |
... |
Problem (Constraints on foreign keys) +.#fk |
3537 |
3538 |
But, the situation is slightly more complex. |
But, the situation is slightly more complex. |
3538 |
3539 |
Test for yourself by editing the following code as indicated: |
Test for yourself by editing the following code as indicated: |
3539 |
3540 |
|
|
3540 |
|
```{.sqlmysql .numberLines include=code/sql/HW_FKtest.sql} |
|
|
3541 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_FKtest.sql} |
3541 |
3542 |
``` |
``` |
3542 |
3543 |
|
|
3543 |
3544 |
#. Remove the `PRIMARY KEY` constraint. |
#. Remove the `PRIMARY KEY` constraint. |
|
... |
... |
Problem (Revisiting the PROF table) +.#profrevisited |
3567 |
3568 |
|
|
3568 |
3569 |
The code we studied during the lecture is more or less the following. |
The code we studied during the lecture is more or less the following. |
3569 |
3570 |
|
|
3570 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExampleRevisitedRevisited.sql snippet=recreate} |
|
|
3571 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ProfExampleRevisitedRevisited.sql snippet=recreate} |
3571 |
3572 |
``` |
``` |
3572 |
3573 |
|
|
3573 |
3574 |
We will resume working on this model, and enhance it. |
We will resume working on this model, and enhance it. |
|
... |
... |
Problem (TRAIN table and more advanced `SQL` coding) +.#train |
3635 |
3636 |
Look at the `SQL` code below and then answer the following questions. |
Look at the `SQL` code below and then answer the following questions. |
3636 |
3637 |
|
|
3637 |
3638 |
|
|
3638 |
|
```{.sqlmysql .numberLines include=code/sql/HW_Train.sql snippet=set-up} |
|
|
3639 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_Train.sql snippet=set-up} |
3639 |
3640 |
``` |
``` |
3640 |
3641 |
|
|
3641 |
3642 |
@problem:train -- Question -.# |
@problem:train -- Question -.# |
|
... |
... |
Problem (Write select queries for the DEPARTMENT table) +.#DepartmentSelect |
3800 |
3801 |
|
|
3801 |
3802 |
Consider the following `SQL` code: |
Consider the following `SQL` code: |
3802 |
3803 |
|
|
3803 |
|
```{.sqlmysql .numberLines include=code/sql/HW_Department.sql snippet=statement} |
|
|
3804 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_Department.sql snippet=statement} |
3804 |
3805 |
``` |
``` |
3805 |
3806 |
|
|
3806 |
3807 |
Write queries that return the following information. The values returned *in this set-up* will be in parenthesis, but keep the queries general. |
Write queries that return the following information. The values returned *in this set-up* will be in parenthesis, but keep the queries general. |
|
... |
... |
Problem (Write select queries for the COMPUTER table) +.#ComputerSelect |
3817 |
3818 |
|
|
3818 |
3819 |
Consider the following `SQL` code: |
Consider the following `SQL` code: |
3819 |
3820 |
|
|
3820 |
|
```{.sqlmysql .numberLines include=code/sql/HW_Computer.sql} |
|
|
3821 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_Computer.sql} |
3821 |
3822 |
``` |
``` |
3822 |
3823 |
|
|
3823 |
3824 |
Write queries that return the following information. The values returned *in this set-up* will be in parenthesis, but keep the queries general. |
Write queries that return the following information. The values returned *in this set-up* will be in parenthesis, but keep the queries general. |
|
... |
... |
Problem (Write select queries for the SocialMedia schema) +.#SocialMedia |
3834 |
3835 |
|
|
3835 |
3836 |
Consider the following `SQL` code: |
Consider the following `SQL` code: |
3836 |
3837 |
|
|
3837 |
|
```{.sqlmysql .numberLines include=code/sql/HW_SocialMedia.sql snippet=set-up} |
|
|
3838 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_SocialMedia.sql snippet=set-up} |
3838 |
3839 |
``` |
``` |
3839 |
3840 |
|
|
3840 |
3841 |
Write queries that return the following information. The values returned *in this set-up* will be in parenthesis, but keep the queries general. |
Write queries that return the following information. The values returned *in this set-up* will be in parenthesis, but keep the queries general. |
|
... |
... |
Problem (Write select queries for a variation of the COMPUTER table) +.#Computer |
3857 |
3858 |
|
|
3858 |
3859 |
Consider the following `SQL` code: |
Consider the following `SQL` code: |
3859 |
3860 |
|
|
3860 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ComputerVariation.sql snippet=set-up} |
|
|
3861 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ComputerVariation.sql snippet=set-up} |
3861 |
3862 |
``` |
``` |
3862 |
3863 |
|
|
3863 |
3864 |
Write queries that return the following information. The values returned *in this set-up* will be in parenthesis, but keep the queries general. |
Write queries that return the following information. The values returned *in this set-up* will be in parenthesis, but keep the queries general. |
|
... |
... |
Problem (A simple database for books) +.#sqlBooks |
3920 |
3921 |
|
|
3921 |
3922 |
Consider the following code: |
Consider the following code: |
3922 |
3923 |
|
|
3923 |
|
```{.sqlmysql .numberLines include=code/sql/HW_SimpleBook.sql} |
|
|
3924 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_SimpleBook.sql} |
3924 |
3925 |
``` |
``` |
3925 |
3926 |
|
|
3926 |
3927 |
The values inserted in the database is just to provide some examples; you should assume there is more data in it than what we have inserted. |
The values inserted in the database is just to provide some examples; you should assume there is more data in it than what we have inserted. |
|
... |
... |
Problem (A simple database for published pieces of work) +.#sqlWorks |
4032 |
4033 |
|
|
4033 |
4034 |
Consider the following code: |
Consider the following code: |
4034 |
4035 |
|
|
4035 |
|
```{.sqlmysql .numberLines include=code/sql/HW_Work.sql snippet=set-up} |
|
|
4036 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_Work.sql snippet=set-up} |
4036 |
4037 |
``` |
``` |
4037 |
4038 |
|
|
4038 |
4039 |
Assume the following: |
Assume the following: |
|
... |
... |
Problem (A simple database for authors of textbooks) +.#project1 |
4104 |
4105 |
Consider the following code: |
Consider the following code: |
4105 |
4106 |
|
|
4106 |
4107 |
|
|
4107 |
|
```{.sqlmysql .numberLines include=code/sql/HW_TextbookAuthored.sql} |
|
|
4108 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_TextbookAuthored.sql} |
4108 |
4109 |
``` |
``` |
4109 |
4110 |
The meaning of the `AUTHORED` table is that a tuple $<I, L, F>$ represents that the author whose last name is L and whose first name is F wrote the textbook whose ISBN is I. |
The meaning of the `AUTHORED` table is that a tuple $<I, L, F>$ represents that the author whose last name is L and whose first name is F wrote the textbook whose ISBN is I. |
4110 |
4111 |
|
|
|
... |
... |
Problem (A simple database for capstone projects) +.#project1bis |
4137 |
4138 |
Consider the following code: |
Consider the following code: |
4138 |
4139 |
|
|
4139 |
4140 |
|
|
4140 |
|
```{.sqlmysql .numberLines include=code/sql/HW_Capstone.sql} |
|
|
4141 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_Capstone.sql} |
4141 |
4142 |
``` |
``` |
4142 |
4143 |
The meaning of the USED_LANGUAGE table is that a tuple $< N, L, U>$ represents the fact that the project whose code name is $N$ and whose leader is $L$ uses the programming language $U$. |
The meaning of the USED_LANGUAGE table is that a tuple $< N, L, U>$ represents the fact that the project whose code name is $N$ and whose leader is $L$ uses the programming language $U$. |
4143 |
4144 |
|
|
|
... |
... |
Problem (A database for residencies) +.#residency |
4178 |
4179 |
Consider the following code: |
Consider the following code: |
4179 |
4180 |
|
|
4180 |
4181 |
|
|
4181 |
|
```{.sqlmysql .numberLines include=code/sql/HW_Residency.sql} |
|
|
4182 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_Residency.sql} |
4182 |
4183 |
``` |
``` |
4183 |
4184 |
Note that each row inserted in the `PERSON`, `HOUSE` and `RESIDENCY` tables is given the name and noted as afterwards as a comment (`"P.1, P.2, P.3, P.4, H.1"`, etc.). |
Note that each row inserted in the `PERSON`, `HOUSE` and `RESIDENCY` tables is given the name and noted as afterwards as a comment (`"P.1, P.2, P.3, P.4, H.1"`, etc.). |
4184 |
4185 |
|
|
|
... |
... |
Problem (A database for research fundings) +.#research-funding |
4245 |
4246 |
Consider the following code: |
Consider the following code: |
4246 |
4247 |
|
|
4247 |
4248 |
|
|
4248 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ScientificResearch.sql snippet=statement} |
|
|
4249 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ScientificResearch.sql snippet=statement} |
4249 |
4250 |
``` |
``` |
4250 |
4251 |
Note that each row inserted in the tables is given a name and noted as afterwards as a comment (`"S.1, S.2, P.1, C.1, FA.1"`, etc.). |
Note that each row inserted in the tables is given a name and noted as afterwards as a comment (`"S.1, S.2, P.1, C.1, FA.1"`, etc.). |
4251 |
4252 |
|
|
|
... |
... |
Solution to [%D %n (%T)](#problem:profrevisited) |
4601 |
4602 |
|
|
4602 |
4603 |
The code is straightforward: |
The code is straightforward: |
4603 |
4604 |
|
|
4604 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExampleRevisitedRevisited.sql snippet=lecture} |
|
|
4605 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ProfExampleRevisitedRevisited.sql snippet=lecture} |
4605 |
4606 |
``` |
``` |
4606 |
4607 |
However, this representation can not handle the following situations: |
However, this representation can not handle the following situations: |
4607 |
4608 |
|
|
|
... |
... |
Solution to [%D %n (%T)](#problem:profrevisited) |
4616 |
4617 |
|
|
4617 |
4618 |
The statements are immediate: |
The statements are immediate: |
4618 |
4619 |
|
|
4619 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExampleRevisitedRevisited.sql snippet=grade} |
|
|
4620 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ProfExampleRevisitedRevisited.sql snippet=grade} |
4620 |
4621 |
``` |
``` |
4621 |
4622 |
|
|
4622 |
4623 |
What may be surprising is that the values for `LectureCode` and `LectureYear` are set to `NULL` in all the tuples. |
What may be surprising is that the values for `LectureCode` and `LectureYear` are set to `NULL` in all the tuples. |
|
... |
... |
Solution to [%D %n (%T)](#problem:profrevisited) |
4626 |
4627 |
|
|
4627 |
4628 |
We use `UPDATE` statements: |
We use `UPDATE` statements: |
4628 |
4629 |
|
|
4629 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExampleRevisitedRevisited.sql snippet=update} |
|
|
4630 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ProfExampleRevisitedRevisited.sql snippet=update} |
4630 |
4631 |
``` |
``` |
4631 |
4632 |
|
|
4632 |
4633 |
@problem:profrevisited-- Solution to Q. -.# |
@problem:profrevisited-- Solution to Q. -.# |
|
... |
... |
Solution to [%D %n (%T)](#problem:profrevisited) |
4638 |
4639 |
|
|
4639 |
4640 |
We use `SELECT` statements: |
We use `SELECT` statements: |
4640 |
4641 |
|
|
4641 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExampleRevisitedRevisited.sql snippet=select} |
|
|
4642 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ProfExampleRevisitedRevisited.sql snippet=select} |
4642 |
4643 |
``` |
``` |
4643 |
4644 |
--- |
--- |
4644 |
4645 |
|
|
|
... |
... |
Solution to [%D %n (%T)](#problem:train) |
4647 |
4648 |
|
|
4648 |
4649 |
The code below includes the answers to all of the questions for this problem: |
The code below includes the answers to all of the questions for this problem: |
4649 |
4650 |
|
|
4650 |
|
```{.sqlmysql .numberLines include=code/sql/HW_Train.sql snippet=solution} |
|
|
4651 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_Train.sql snippet=solution} |
4651 |
4652 |
``` |
``` |
4652 |
4653 |
|
|
4653 |
4654 |
--- |
--- |
|
... |
... |
Solution to [%D %n (%T)](#problem:coffee) |
4668 |
4669 |
|
|
4669 |
4670 |
The answers to the rest of the questions are in the following code: |
The answers to the rest of the questions are in the following code: |
4670 |
4671 |
|
|
4671 |
|
```{.sqlmysql .numberLines include=code/sql/HW_DBCoffee.sql snippet=solution} |
|
|
4672 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_DBCoffee.sql snippet=solution} |
4672 |
4673 |
``` |
``` |
4673 |
4674 |
|
|
4674 |
4675 |
--- |
--- |
|
... |
... |
Solution to [%D %n (%T)](#problem:DepartmentSelect) |
4677 |
4678 |
|
|
4678 |
4679 |
~ |
~ |
4679 |
4680 |
|
|
4680 |
|
#. ```{.sqlmysql .numberLines include=code/sql/HW_Department.sql snippet=solution1} |
|
|
4681 |
|
#. ```{.sqlmysql .numberLines .includeLink include=code/sql/HW_Department.sql snippet=solution1} |
4681 |
4682 |
``` |
``` |
4682 |
4683 |
|
|
4683 |
|
#. ```{.sqlmysql .numberLines include=code/sql/HW_Department.sql snippet=solution2} |
|
|
4684 |
|
#. ```{.sqlmysql .numberLines .includeLink include=code/sql/HW_Department.sql snippet=solution2} |
4684 |
4685 |
``` |
``` |
4685 |
4686 |
|
|
4686 |
|
#. ```{.sqlmysql .numberLines include=code/sql/HW_Department.sql snippet=solution3} |
|
|
4687 |
|
#. ```{.sqlmysql .numberLines .includeLink include=code/sql/HW_Department.sql snippet=solution3} |
4687 |
4688 |
``` |
``` |
4688 |
4689 |
--- |
--- |
4689 |
4690 |
|
|
|
... |
... |
Solution to [%D %n (%T)](#problem:ComputerSelectBis) |
4691 |
4692 |
|
|
4692 |
4693 |
~ |
~ |
4693 |
4694 |
|
|
4694 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ComputerVariation.sql snippet=solution} |
|
|
4695 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ComputerVariation.sql snippet=solution} |
4695 |
4696 |
``` |
``` |
4696 |
4697 |
|
|
4697 |
4698 |
--- |
--- |
|
... |
... |
Solution to [%D %n (%T)](#problem:ComputerSelectBis) |
4699 |
4700 |
Solution to [%D %n (%T)](#problem:SocialMedia) |
Solution to [%D %n (%T)](#problem:SocialMedia) |
4700 |
4701 |
~ |
~ |
4701 |
4702 |
|
|
4702 |
|
```{.sqlmysql .numberLines include=code/sql/HW_SocialMedia.sql snippet=solution} |
|
|
4703 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_SocialMedia.sql snippet=solution} |
4703 |
4704 |
``` |
``` |
4704 |
4705 |
|
|
4705 |
4706 |
|
|
|
... |
... |
Solution to [%D %n (%T)](#problem:certificate) |
4855 |
4856 |
|
|
4856 |
4857 |
The solution can be read from the following code: |
The solution can be read from the following code: |
4857 |
4858 |
|
|
4858 |
|
```{.sqlmysql .numberLines include=code/sql/HW_Certificate.sql} |
|
|
4859 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_Certificate.sql} |
4859 |
4860 |
``` |
``` |
4860 |
4861 |
|
|
4861 |
4862 |
|
|
|
... |
... |
Solution to [%D %n (%T)](#problem:sqlWorks) |
4883 |
4884 |
The solution to the next questions can be read from the following code: |
The solution to the next questions can be read from the following code: |
4884 |
4885 |
|
|
4885 |
4886 |
|
|
4886 |
|
```{.sqlmysql .numberLines include=code/sql/HW_Work.sql snippet=solution} |
|
|
4887 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_Work.sql snippet=solution} |
4887 |
4888 |
``` |
``` |
4888 |
4889 |
|
|
4889 |
4890 |
@problem:sqlWorks -- Solution to Q. -.# |
@problem:sqlWorks -- Solution to Q. -.# |
|
... |
... |
Solution to [%D %n (%T)](#problem:project1) |
4901 |
4902 |
~ |
~ |
4902 |
4903 |
The answers can be found in the following snippet: |
The answers can be found in the following snippet: |
4903 |
4904 |
|
|
4904 |
|
```{.sqlmysql .numberLines include=code/sql/HW_TextbookAuthoredSol.sql snippet=solution} |
|
|
4905 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_TextbookAuthoredSol.sql snippet=solution} |
4905 |
4906 |
``` |
``` |
4906 |
4907 |
|
|
4907 |
4908 |
--- |
--- |
|
... |
... |
Solution to [%D %n (%T)](#problem:project1bis) |
4910 |
4911 |
~ |
~ |
4911 |
4912 |
The answers can be found in the following snippet: |
The answers can be found in the following snippet: |
4912 |
4913 |
|
|
4913 |
|
```{.sqlmysql .numberLines include=code/sql/HW_CapstoneSol.sql snippet=solution} |
|
|
4914 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_CapstoneSol.sql snippet=solution} |
4914 |
4915 |
``` |
``` |
4915 |
4916 |
|
|
4916 |
4917 |
--- |
--- |
|
... |
... |
Solution to [%D %n (%T)](#problem:residency) |
4970 |
4971 |
|
|
4971 |
4972 |
The answers can be found in the following snippet: |
The answers can be found in the following snippet: |
4972 |
4973 |
|
|
4973 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ResidencySol.sql snippet=solution4} |
|
|
4974 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ResidencySol.sql snippet=solution4} |
4974 |
4975 |
``` |
``` |
4975 |
4976 |
|
|
4976 |
4977 |
@problem:residency -- Solution to Q. -.# |
@problem:residency -- Solution to Q. -.# |
|
... |
... |
Solution to [%D %n (%T)](#problem:residency) |
4978 |
4979 |
|
|
4979 |
4980 |
The answers can be found in the following snippet: |
The answers can be found in the following snippet: |
4980 |
4981 |
|
|
4981 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ResidencySol.sql snippet=solution5} |
|
|
4982 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ResidencySol.sql snippet=solution5} |
4982 |
4983 |
``` |
``` |
4983 |
4984 |
|
|
4984 |
4985 |
Note that the query that returns the name of the homeowners can be improved. |
Note that the query that returns the name of the homeowners can be improved. |
4985 |
4986 |
|
|
4986 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ResidencySol.sql snippet=homonyms} |
|
|
4987 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ResidencySol.sql snippet=homonyms} |
4987 |
4988 |
``` |
``` |
4988 |
4989 |
|
|
4989 |
4990 |
@problem:residency -- Solution to Q. -.# |
@problem:residency -- Solution to Q. -.# |
|
... |
... |
Solution to [%D %n (%T)](#problem:research-funding) |
5035 |
5036 |
~ |
~ |
5036 |
5037 |
(Some of) the answers can be found in the following snippet: |
(Some of) the answers can be found in the following snippet: |
5037 |
5038 |
|
|
5038 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ScientificResearchSol.sql snippet=solution} |
|
|
5039 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_ScientificResearchSol.sql snippet=solution} |
5039 |
5040 |
``` |
``` |
5040 |
5041 |
|
|
5041 |
5042 |
|
|
|
... |
... |
It is possible to go from relational models to ER models, and sometimes needed: |
5456 |
5457 |
For instance, consider the code we studied in ["A First Example"](#a-first-example): |
For instance, consider the code we studied in ["A First Example"](#a-first-example): |
5457 |
5458 |
|
|
5458 |
5459 |
|
|
5459 |
|
```{.sqlmysql .numberLines include=code/sql/HW_Storm.sql snippet=schema} |
|
|
5460 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_Storm.sql snippet=schema} |
5460 |
5461 |
``` |
``` |
5461 |
5462 |
|
|
5462 |
5463 |
It corresponds to the following relational model: |
It corresponds to the following relational model: |
|
... |
... |
Solution to [%D %n (%T)](#problem:reverseeng) |
7969 |
7970 |
|
|
7970 |
7971 |
We give the code first, then the drawing: |
We give the code first, then the drawing: |
7971 |
7972 |
|
|
7972 |
|
```{.sqlmysql .numberLines include=code/sql/HW_Person.sql} |
|
|
7973 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_Person.sql} |
7973 |
7974 |
``` |
``` |
7974 |
7975 |
|
|
7975 |
7976 |
 |
 |
|
... |
... |
Even if the creation and population of the database could have been done from wi |
8041 |
8042 |
|
|
8042 |
8043 |
For this program, we will use the following database: |
For this program, we will use the following database: |
8043 |
8044 |
|
|
8044 |
|
```{.sqlmysql .numberLines include=code/sql/HW_EBookshop.sql} |
|
|
8045 |
|
```{.sqlmysql .numberLines .includeLink include=code/sql/HW_EBookshop.sql} |
8045 |
8046 |
``` |
``` |
8046 |
8047 |
|
|
8047 |
8048 |
```{.default.numberlines} |
```{.default.numberlines} |
|
... |
... |
at FirstProg.main(FirstProg.java:9) |
8130 |
8131 |
### The Application Program (`java`) |
### The Application Program (`java`) |
8131 |
8132 |
|
|
8132 |
8133 |
|
|
8133 |
|
```{.java .numberLines include=code/java/FirstProg.java} |
|
|
8134 |
|
```{.java .numberLines .includeLink include=code/java/FirstProg.java} |
8134 |
8135 |
``` |
``` |
8135 |
8136 |
|
|
8136 |
8137 |
A couple of comments: |
A couple of comments: |
|
... |
... |
Take the time to make sure you have the same result on your installation, and th |
8186 |
8187 |
|
|
8187 |
8188 |
If you were to replace the body of `try` in the previous program with |
If you were to replace the body of `try` in the previous program with |
8188 |
8189 |
|
|
8189 |
|
```{.java .numberLines dedent=6 include=code/java/FirstProgBis.java snippet=alternate} |
|
|
8190 |
|
```{.java .numberLines dedent=6 .includeLink include=code/java/FirstProgBis.java snippet=alternate} |
8190 |
8191 |
``` |
``` |
8191 |
8192 |
|
|
8192 |
8193 |
You would obtain: |
You would obtain: |
|
... |
... |
Please refer to it once you are done with this section. |
8257 |
8258 |
|
|
8258 |
8259 |
We can pass options (values of fields) when connecting to the database: |
We can pass options (values of fields) when connecting to the database: |
8259 |
8260 |
|
|
8260 |
|
```{.java .numberLines dedent=6 include=code/java/AdvancedProg.java snippet=passing-options} |
|
|
8261 |
|
```{.java .numberLines dedent=6 .includeLink include=code/java/AdvancedProg.java snippet=passing-options} |
8261 |
8262 |
``` |
``` |
8262 |
8263 |
|
|
8263 |
8264 |
On top of `user` and `password` (which are self-explanatory), setting `allowMultiQueries` to `true` allows to pass multiple queries with one `executeUpdate` statement, and `createDatabaseIfNotExist` creates the _schema_ passed in the `url` (so, here, `HW_DBPROG`) if it does not already exists. |
On top of `user` and `password` (which are self-explanatory), setting `allowMultiQueries` to `true` allows to pass multiple queries with one `executeUpdate` statement, and `createDatabaseIfNotExist` creates the _schema_ passed in the `url` (so, here, `HW_DBPROG`) if it does not already exists. |
|
... |
... |
You can read about other options at <https://dev.mysql.com/doc/connector-j/8.0/e |
8287 |
8288 |
### Creating a Table |
### Creating a Table |
8288 |
8289 |
|
|
8289 |
8290 |
We can create a table with the method `stmt.execute`. |
We can create a table with the method `stmt.execute`. |
8290 |
|
```{.java .numberLines dedent=6 include=code/java/AdvancedProg.java snippet=table-creation} |
|
|
8291 |
|
```{.java .numberLines dedent=6 .includeLink include=code/java/AdvancedProg.java snippet=table-creation} |
8291 |
8292 |
``` |
``` |
8292 |
8293 |
|
|
8293 |
8294 |
If we were to execute `SHOW TABLES;` after this `execute` instruction directly in the MySQL interpreter, this would display at the screen: |
If we were to execute `SHOW TABLES;` after this `execute` instruction directly in the MySQL interpreter, this would display at the screen: |
|
... |
... |
But here, to access this information, we will use the connection's metadata. |
8304 |
8305 |
The `DatabaseMetaData` is a class used to get information about the database: the driver, the user, the versions, etc. |
The `DatabaseMetaData` is a class used to get information about the database: the driver, the user, the versions, etc. |
8305 |
8306 |
We can use the `getMetaData()` method of this class to obtain information about the schema we just created: |
We can use the `getMetaData()` method of this class to obtain information about the schema we just created: |
8306 |
8307 |
|
|
8307 |
|
```{.java .numberLines dedent=6 include=code/java/AdvancedProg.java snippet=table-metadata-1 } |
|
|
8308 |
|
```{.java .numberLines dedent=6 .includeLink include=code/java/AdvancedProg.java snippet=table-metadata-1 } |
8308 |
8309 |
``` |
``` |
8309 |
8310 |
|
|
8310 |
8311 |
The first parameter of `getMetaData()` is the schema's name, as you probably guessed, and the the third parameter is `String tableNamePattern`, i.e., what must match the table name stored in the database to be selected. |
The first parameter of `getMetaData()` is the schema's name, as you probably guessed, and the the third parameter is `String tableNamePattern`, i.e., what must match the table name stored in the database to be selected. |
|
... |
... |
The `getMetaData()` method returns a `ResultSet` (here named `rs`), where `3` is |
8314 |
8315 |
We can now iterate over this `rs` object to list all the elements in it, as we would with any `ResultSet` object: |
We can now iterate over this `rs` object to list all the elements in it, as we would with any `ResultSet` object: |
8315 |
8316 |
|
|
8316 |
8317 |
|
|
8317 |
|
```{.java .numberLines dedent=6 include=code/java/AdvancedProg.java snippet=table-metadata-2 } |
|
|
8318 |
|
```{.java .numberLines dedent=6 .includeLink include=code/java/AdvancedProg.java snippet=table-metadata-2 } |
8318 |
8319 |
``` |
``` |
8319 |
8320 |
|
|
8320 |
8321 |
You can read at <https://docs.oracle.com/javase/7/docs/api/java/sql/DatabaseMetaData.html#getTables(java.lang.String,%20java.lang.String,%20java.lang.String,%20java.lang.String[])> the full specification of this method. |
You can read at <https://docs.oracle.com/javase/7/docs/api/java/sql/DatabaseMetaData.html#getTables(java.lang.String,%20java.lang.String,%20java.lang.String,%20java.lang.String[])> the full specification of this method. |
|
... |
... |
You can read at <https://docs.oracle.com/javase/7/docs/api/java/sql/DatabaseMeta |
8324 |
8325 |
|
|
8325 |
8326 |
To insert values in our table, we can use `stmt.executeUpdate`: |
To insert values in our table, we can use `stmt.executeUpdate`: |
8326 |
8327 |
|
|
8327 |
|
```{.java .numberLines dedent=6 include=code/java/AdvancedProg.java snippet=inserting-1 } |
|
|
8328 |
|
```{.java .numberLines dedent=6 .includeLink include=code/java/AdvancedProg.java snippet=inserting-1 } |
8328 |
8329 |
``` |
``` |
8329 |
8330 |
|
|
8330 |
8331 |
Note that the `executeUpdate` returns an integer, the number of rows changed. |
Note that the `executeUpdate` returns an integer, the number of rows changed. |
8331 |
8332 |
We can even use this method to perform multiple insertions at the same time, if `allowMultiQueries` was set to true, cf. <https://stackoverflow.com/a/10804730/>: |
We can even use this method to perform multiple insertions at the same time, if `allowMultiQueries` was set to true, cf. <https://stackoverflow.com/a/10804730/>: |
8332 |
8333 |
|
|
8333 |
|
```{.java .numberLines dedent=6 include=code/java/AdvancedProg.java snippet=inserting-2 } |
|
|
8334 |
|
```{.java .numberLines dedent=6 .includeLink include=code/java/AdvancedProg.java snippet=inserting-2 } |
8334 |
8335 |
``` |
``` |
8335 |
8336 |
|
|
8336 |
8337 |
Another way of "batch processing" statements (i.e., of executing multiple insertions at the same time) is to use `addBatch` (that "loads" statements in the `statement` object) and `executeBatch()` (that execute all the statement loaded): |
Another way of "batch processing" statements (i.e., of executing multiple insertions at the same time) is to use `addBatch` (that "loads" statements in the `statement` object) and `executeBatch()` (that execute all the statement loaded): |
8337 |
8338 |
|
|
8338 |
|
```{.java .numberLines dedent=6 include=code/java/AdvancedProg.java snippet=inserting-3 } |
|
|
8339 |
|
```{.java .numberLines dedent=6 .includeLink include=code/java/AdvancedProg.java snippet=inserting-3 } |
8339 |
8340 |
``` |
``` |
8340 |
8341 |
|
|
8341 |
8342 |
Note that the database is not sollicited until the `executeBatch` method is called: we simply loaded the instruction in the program, and connect to the database only once, with all the instructions, when this `executeBatch()` instruction is met. |
Note that the database is not sollicited until the `executeBatch` method is called: we simply loaded the instruction in the program, and connect to the database only once, with all the instructions, when this `executeBatch()` instruction is met. |
|
... |
... |
Compared to executing `SQL` statements directly, prepared statements have three |
8360 |
8361 |
|
|
8361 |
8362 |
Let us look at a first example: |
Let us look at a first example: |
8362 |
8363 |
|
|
8363 |
|
```{.java .numberLines dedent=6 include=code/java/AdvancedProg.java snippet=prepared-queries-1} |
|
|
8364 |
|
```{.java .numberLines dedent=6 .includeLink include=code/java/AdvancedProg.java snippet=prepared-queries-1} |
8364 |
8365 |
``` |
``` |
8365 |
8366 |
|
|
8366 |
8367 |
Note that once the `ps` `PreparedStatement` object is created, we cannot change the content of the query, beside instantiating the slot. |
Note that once the `ps` `PreparedStatement` object is created, we cannot change the content of the query, beside instantiating the slot. |
|
... |
... |
cf. e.g. the discussion at <https://stackoverflow.com/q/25902881/>. |
8369 |
8370 |
As we said earlier, a prepared statement can have multiple "slots", as we can see in that second example: |
As we said earlier, a prepared statement can have multiple "slots", as we can see in that second example: |
8370 |
8371 |
|
|
8371 |
8372 |
|
|
8372 |
|
```{.java .numberLines dedent=6 include=code/java/AdvancedProg.java snippet=prepared-queries-2} |
|
|
8373 |
|
```{.java .numberLines dedent=6 .includeLink include=code/java/AdvancedProg.java snippet=prepared-queries-2} |
8373 |
8374 |
``` |
``` |
8374 |
8375 |
|
|
8375 |
8376 |
Where we stored the integer value returned by `executeUpdate` and displayed the the prepared statement using the`toString` method. |
Where we stored the integer value returned by `executeUpdate` and displayed the the prepared statement using the`toString` method. |
8376 |
8377 |
|
|
8377 |
8378 |
If we try to mess things up, i.e., provide wrong datatypes: |
If we try to mess things up, i.e., provide wrong datatypes: |
8378 |
8379 |
|
|
8379 |
|
```{.java .numberLines dedent=6 include=code/java/AdvancedProg.java snippet=prepared-queries-3} |
|
|
8380 |
|
```{.java .numberLines dedent=6 .includeLink include=code/java/AdvancedProg.java snippet=prepared-queries-3} |
8380 |
8381 |
``` |
``` |
8381 |
8382 |
Java compiler will be ok, but we'll have an error at execution time when executing the query. |
Java compiler will be ok, but we'll have an error at execution time when executing the query. |
8382 |
8383 |
|
|
|
... |
... |
since `"Not-an-integer"` is not … a valid integer! |
8391 |
8392 |
Of course, prepared statements are particularly convenient when you want to automate some tasks or repeat them multiple times, as you write the query only once, and then re-use it. |
Of course, prepared statements are particularly convenient when you want to automate some tasks or repeat them multiple times, as you write the query only once, and then re-use it. |
8392 |
8393 |
For instance, inserting the whole "Saw" franchise can be made into a loop: |
For instance, inserting the whole "Saw" franchise can be made into a loop: |
8393 |
8394 |
|
|
8394 |
|
```{.java .numberLines dedent=6 include=code/java/AdvancedProg.java snippet=prepared-queries-4} |
|
|
8395 |
|
```{.java .numberLines dedent=6 .includeLink include=code/java/AdvancedProg.java snippet=prepared-queries-4} |
8395 |
8396 |
``` |
``` |
8396 |
8397 |
|
|
8397 |
8398 |
### More Complex Statement Objects |
### More Complex Statement Objects |
8398 |
8399 |
|
|
8399 |
8400 |
When you create the `Statement` objects, you can give two arguments to the `createStatement` method: |
When you create the `Statement` objects, you can give two arguments to the `createStatement` method: |
8400 |
8401 |
|
|
8401 |
|
```{.java .numberLines dedent=6 include=code/java/AdvancedProg.java snippet=new-statement-1} |
|
|
8402 |
|
```{.java .numberLines dedent=6 .includeLink include=code/java/AdvancedProg.java snippet=new-statement-1} |
8402 |
8403 |
``` |
``` |
8403 |
8404 |
|
|
8404 |
8405 |
Those options change two things about the ResultSet we obtain using this statement |
Those options change two things about the ResultSet we obtain using this statement |
|
... |
... |
This `createStatement` method is documented at <https://docs.oracle.com/javase/7 |
8429 |
8430 |
You can find below a simple example of "scrollable" `ResultSet`: |
You can find below a simple example of "scrollable" `ResultSet`: |
8430 |
8431 |
|
|
8431 |
8432 |
|
|
8432 |
|
```{.java .numberLines include=code/java/ScrollingProgram.java} |
|
|
8433 |
|
```{.java .numberLines .includeLink include=code/java/ScrollingProgram.java} |
8433 |
8434 |
``` |
``` |
8434 |
8435 |
|
|
8435 |
8436 |
You can also have a look at the end of `code/java/AdvancedProg.java`, which creates a second `Statement` object is created and used. |
You can also have a look at the end of `code/java/AdvancedProg.java`, which creates a second `Statement` object is created and used. |
|
... |
... |
But if the task is essentially a series of queries, then creating a procedure ma |
8451 |
8452 |
|
|
8452 |
8453 |
As an example of how to technically declare and use a procedure from an application, refer to the following code: |
As an example of how to technically declare and use a procedure from an application, refer to the following code: |
8453 |
8454 |
|
|
8454 |
|
```{.java .numberLines include=code/java/CallProcedure.java} |
|
|
8455 |
|
```{.java .numberLines .includeLink include=code/java/CallProcedure.java} |
8455 |
8456 |
``` |
``` |
8456 |
8457 |
|
|
8457 |
8458 |
|
|
|
... |
... |
Exercise +.#ErrorsInCode |
8564 |
8565 |
They are *not* subtle Java errors (like misspelling a key word) and do not come from the DBMS (so you should assume that the password is correct, that the database exists, etc.). |
They are *not* subtle Java errors (like misspelling a key word) and do not come from the DBMS (so you should assume that the password is correct, that the database exists, etc.). |
8565 |
8566 |
Highlight each error and explain why it is an error. |
Highlight each error and explain why it is an error. |
8566 |
8567 |
|
|
8567 |
|
```{.java .numberLines include=code/java/ProgWithErrors.java} |
|
|
8568 |
|
```{.java .numberLines .includeLink include=code/java/ProgWithErrors.java} |
8568 |
8569 |
``` |
``` |
8569 |
8570 |
|
|
8570 |
8571 |
Exercise +.# |
Exercise +.# |
|
... |
... |
Solution +.# |
8741 |
8742 |
Here is what the program should look like: |
Here is what the program should look like: |
8742 |
8743 |
|
|
8743 |
8744 |
|
|
8744 |
|
```{.java .numberLines include=code/java/TestForNull.java} |
|
|
8745 |
|
```{.java .numberLines .includeLink include=code/java/TestForNull.java} |
8745 |
8746 |
``` |
``` |
8746 |
8747 |
|
|
8747 |
8748 |
This program should display: |
This program should display: |
|
... |
... |
Problem (Advanced Java Programming) +.#Advanced_java |
8759 |
8760 |
|
|
8760 |
8761 |
Read, execute, break, edit, compile, patch, hack and (most importantly) understand the following program: |
Read, execute, break, edit, compile, patch, hack and (most importantly) understand the following program: |
8761 |
8762 |
|
|
8762 |
|
```{.java .numberLines include=code/java/AdvancedProg.java} |
|
|
8763 |
|
```{.java .numberLines .includeLink include=code/java/AdvancedProg.java} |
8763 |
8764 |
``` |
``` |
8764 |
8765 |
|
|
8765 |
8766 |
Problem (A GUEST Java Program) +.#Guest_Java |
Problem (A GUEST Java Program) +.#Guest_Java |
|
... |
... |
Problem (A GUEST Java Program) +.#Guest_Java |
8767 |
8768 |
|
|
8768 |
8769 |
Consider the code below: |
Consider the code below: |
8769 |
8770 |
|
|
8770 |
|
```{.java .numberLines include=code/java/GuestProgram.java} |
|
|
8771 |
|
```{.java .numberLines .includeLink include=code/java/GuestProgram.java} |
8771 |
8772 |
``` |
``` |
8772 |
8773 |
|
|
8773 |
8774 |
In the following three exercises, you will add some code below the comment `// INSERT HERE Solution to exercises 1, 2 and 3.`{.java} in order to obtain a behavior like the following one (you do not have to reproduce it exactly!). |
In the following three exercises, you will add some code below the comment `// INSERT HERE Solution to exercises 1, 2 and 3.`{.java} in order to obtain a behavior like the following one (you do not have to reproduce it exactly!). |
|
... |
... |
Solution to [%D %n (%T)](#problem:Guest_Java) |
8812 |
8813 |
|
|
8813 |
8814 |
They both starts with: |
They both starts with: |
8814 |
8815 |
|
|
8815 |
|
```{.java .numberLines dedent=6 include=code/java/GuestProgramSolution.java snippet=exercise-1-intro} |
|
|
8816 |
|
```{.java .numberLines dedent=6 .includeLink include=code/java/GuestProgramSolution.java snippet=exercise-1-intro} |
8816 |
8817 |
``` |
``` |
8817 |
8818 |
|
|
8818 |
8819 |
Then the solution using batch processing could be: |
Then the solution using batch processing could be: |
8819 |
8820 |
|
|
8820 |
|
```{.java .numberLines dedent=6 include=code/java/GuestProgramSolution.java snippet=exercise-1-batch } |
|
|
8821 |
|
```{.java .numberLines dedent=6 .includeLink include=code/java/GuestProgramSolution.java snippet=exercise-1-batch } |
8821 |
8822 |
``` |
``` |
8822 |
8823 |
|
|
8823 |
8824 |
while the solution using prepared statements could be: |
while the solution using prepared statements could be: |
|
... |
... |
Solution to [%D %n (%T)](#problem:Guest_Java) |
8838 |
8839 |
|
|
8839 |
8840 |
We let `SQL` do all the hard work: |
We let `SQL` do all the hard work: |
8840 |
8841 |
|
|
8841 |
|
```{.java .numberLines dedent=6 include=code/java/GuestProgramSolution.java snippet=exercise-2} |
|
|
8842 |
|
```{.java .numberLines dedent=6 .includeLink include=code/java/GuestProgramSolution.java snippet=exercise-2} |
8842 |
8843 |
``` |
``` |
8843 |
8844 |
|
|
8844 |
8845 |
@problem:Guest_Java -- Solution to Q. -.# |
@problem:Guest_Java -- Solution to Q. -.# |
8845 |
8846 |
|
|
8846 |
8847 |
Similarly, we let `SQL` do all the hard work: |
Similarly, we let `SQL` do all the hard work: |
8847 |
8848 |
|
|
8848 |
|
```{.java .numberLines dedent=6 include=code/java/GuestProgramSolution.java snippet=exercise-3} |
|
|
8849 |
|
```{.java .numberLines dedent=6 .includeLink include=code/java/GuestProgramSolution.java snippet=exercise-3} |
8849 |
8850 |
``` |
``` |
8850 |
8851 |
|
|
8851 |
8852 |
# A Bit About Security |
# A Bit About Security |
|
... |
... |
We will see two examples of insecure programs (`code/java/SimpleInjection01.java |
8984 |
8985 |
|
|
8985 |
8986 |
The gist of `code/java/SimpleInjection01.java` is that writing a statement like |
The gist of `code/java/SimpleInjection01.java` is that writing a statement like |
8986 |
8987 |
|
|
8987 |
|
```{.java .numberLines dedent=8 include=code/java/SimpleInjection01.java snippet=gist} |
|
|
8988 |
|
```{.java .numberLines dedent=8 .includeLink include=code/java/SimpleInjection01.java snippet=gist} |
8988 |
8989 |
``` |
``` |
8989 |
8990 |
|
|
8990 |
8991 |
leaves the door open for an attacker to enter `n' OR '1' = '1` as a value for `entered`, so that the condition would always be true. |
leaves the door open for an attacker to enter `n' OR '1' = '1` as a value for `entered`, so that the condition would always be true. |
8991 |
8992 |
|
|
8992 |
8993 |
For `code/java/SimpleInjection02.java`, it shows how |
For `code/java/SimpleInjection02.java`, it shows how |
8993 |
8994 |
|
|
8994 |
|
```{.java .numberLines dedent=8 include=code/java/SimpleInjection02.java snippet=gist} |
|
|
8995 |
|
```{.java .numberLines dedent=8 .includeLink include=code/java/SimpleInjection02.java snippet=gist} |
8995 |
8996 |
``` |
``` |
8996 |
8997 |
|
|
8997 |
8998 |
could be a serious issue if `nope'; DROP SCHEMA HW_SIMPLE_INJECTION_2;` was entered as a value for `entered`, destroying the whole schema `HW_SIMPLE_INJECTION_2`. |
could be a serious issue if `nope'; DROP SCHEMA HW_SIMPLE_INJECTION_2;` was entered as a value for `entered`, destroying the whole schema `HW_SIMPLE_INJECTION_2`. |
|
... |
... |
Problem (Insecure Java Programming) +.#insecure_java |
9069 |
9070 |
|
|
9070 |
9071 |
Consider the following code: |
Consider the following code: |
9071 |
9072 |
|
|
9072 |
|
```{.java .numberLines dedent=6 include=code/java/InsecureProgram.java snippet=gist} |
|
|
9073 |
|
```{.java .numberLines dedent=6 .includeLink include=code/java/InsecureProgram.java snippet=gist} |
9073 |
9074 |
``` |
``` |
9074 |
9075 |
|
|
9075 |
9076 |
Assume this software is connecting to a schema in a database hosted at <http://example.com/> using: |
Assume this software is connecting to a schema in a database hosted at <http://example.com/> using: |
|
... |
... |
You can generally convert from one format to the others, which is an important f |
9332 |
9333 |
|
|
9333 |
9334 |
An example of XML (Extensible Markup Languag) document, storing information about what Martin and Pradmod like, which cities they visited, etc.: |
An example of XML (Extensible Markup Languag) document, storing information about what Martin and Pradmod like, which cities they visited, etc.: |
9334 |
9335 |
|
|
9335 |
|
```{.xml .numberLines include=code/xml/person.xml } |
|
|
9336 |
|
```{.xml .numberLines .includeLink include=code/xml/person.xml } |
9336 |
9337 |
``` |
``` |
9337 |
9338 |
|
|
9338 |
9339 |
As you can see, from this document: |
As you can see, from this document: |
|
... |
... |
Each MongoDB instance has multiple databases, each database can have multiple co |
9386 |
9387 |
|
|
9387 |
9388 |
Our previous `XML` "person" example can be converted into two documents^[We actually had to have three documents: as `JSON` does not really have comments (cf. <https://stackoverflow.com/q/244777/>), we added a document containing only the attribute `"_comment"` to specify the path where that file is located.] delimited by `[`…`]`, used to delimit an array of document. |
Our previous `XML` "person" example can be converted into two documents^[We actually had to have three documents: as `JSON` does not really have comments (cf. <https://stackoverflow.com/q/244777/>), we added a document containing only the attribute `"_comment"` to specify the path where that file is located.] delimited by `[`…`]`, used to delimit an array of document. |
9388 |
9389 |
|
|
9389 |
|
```{.json .numberLines include=code/json/person.json } |
|
|
9390 |
|
```{.json .numberLines .includeLink include=code/json/person.json } |
9390 |
9391 |
``` |
``` |
9391 |
9392 |
|
|
9392 |
9393 |
Note that |
Note that |
|
... |
... |
You should see a large number of lines displayed at the screen, and around the t |
9516 |
9517 |
After various import statement, the program create a `MongoClient` object called `mongoClient`, and connects it to the local database server: |
After various import statement, the program create a `MongoClient` object called `mongoClient`, and connects it to the local database server: |
9517 |
9518 |
|
|
9518 |
9519 |
|
|
9519 |
|
```{.sqlmysql .numberLines dedent=4 include=code/java/QuickTour.java snippet=mongoclient} |
|
|
9520 |
|
```{.sqlmysql .numberLines dedent=4 .includeLink include=code/java/QuickTour.java snippet=mongoclient} |
9520 |
9521 |
``` |
``` |
9521 |
9522 |
|
|
9522 |
9523 |
|
|
9523 |
9524 |
To get a database and a collection, the program uses: |
To get a database and a collection, the program uses: |
9524 |
9525 |
|
|
9525 |
|
```{.sqlmysql .numberLines dedent=6 include=code/java/QuickTour.java snippet=db-and-collection} |
|
|
9526 |
|
```{.sqlmysql .numberLines dedent=6 .includeLink include=code/java/QuickTour.java snippet=db-and-collection} |
9526 |
9527 |
``` |
``` |
9527 |
9528 |
|
|
9528 |
9529 |
Note that a collection is simply an [ArrayList](https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html) of documents. |
Note that a collection is simply an [ArrayList](https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html) of documents. |
|
... |
... |
Assume we want to create the following document: |
9545 |
9546 |
|
|
9546 |
9547 |
Then we can use the `Document` class to create it, and then insert the document created: |
Then we can use the `Document` class to create it, and then insert the document created: |
9547 |
9548 |
|
|
9548 |
|
```{.sqlmysql .numberLines dedent=6 include=code/java/QuickTour.java snippet=document-creation} |
|
|
9549 |
|
```{.sqlmysql .numberLines dedent=6 .includeLink include=code/java/QuickTour.java snippet=document-creation} |
9549 |
9550 |
``` |
``` |
9550 |
9551 |
|
|
9551 |
9552 |
Note that we can "chain" the `append`, using `doc.append("type", "database").append("count", 1);` etc. |
Note that we can "chain" the `append`, using `doc.append("type", "database").append("count", 1);` etc. |
|
... |
... |
The program goes on and is discussed in details at <https://mongodb.github.io/mo |
9574 |
9575 |
You can see for instance that to construct lists of documents and insert them, one can use: |
You can see for instance that to construct lists of documents and insert them, one can use: |
9575 |
9576 |
|
|
9576 |
9577 |
|
|
9577 |
|
```{.sqlmysql .numberLines dedent=4 include=code/java/QuickTour.java snippet=documents-creation} |
|
|
9578 |
|
```{.sqlmysql .numberLines dedent=4 .includeLink include=code/java/QuickTour.java snippet=documents-creation} |
9578 |
9579 |
``` |
``` |
9579 |
9580 |
|
|
9580 |
9581 |
A discipline similar to what we saw on Java applications interacting with MySQL should apply: |
A discipline similar to what we saw on Java applications interacting with MySQL should apply: |
|
... |
... |
Problem (ER Diagram from XML File -- Customer) +.#xmltoercustomer |
9671 |
9672 |
|
|
9672 |
9673 |
Consider the following `xml` file: |
Consider the following `xml` file: |
9673 |
9674 |
|
|
9674 |
|
```{.xml .numberLines include=code/xml/customers.xml} |
|
|
9675 |
|
```{.xml .numberLines .includeLink include=code/xml/customers.xml} |
9675 |
9676 |
``` |
``` |
9676 |
9677 |
|
|
9677 |
9678 |
Try to draw the ER model that would correspond to the relational implementation of this database. |
Try to draw the ER model that would correspond to the relational implementation of this database. |
|
... |
... |
Problem (ER Diagram from XML File -- Award) +.#xmltoeraward |
9684 |
9685 |
|
|
9685 |
9686 |
Find below a mashup of actual data from the National Science Foundation (courtesy of <https://www.nsf.gov/awardsearch/download.jsp>): |
Find below a mashup of actual data from the National Science Foundation (courtesy of <https://www.nsf.gov/awardsearch/download.jsp>): |
9686 |
9687 |
|
|
9687 |
|
```{.xml .numberLines include=code/xml/NSFAward.xml} |
|
|
9688 |
|
```{.xml .numberLines .includeLink include=code/xml/NSFAward.xml} |
9688 |
9689 |
``` |
``` |
9689 |
9690 |
|
|
9690 |
9691 |
It contains information about one particular award that was awarded to an institution on behalf of two researchers. |
It contains information about one particular award that was awarded to an institution on behalf of two researchers. |