Commit 055372aa authored by K9272's avatar K9272
Browse files

H8

parent 10aa9d9b
# Viikko 8 Alikyselyt, näkymät ja indeksointi
## Tehtävä 1 [2p]
Luo sellainen triggeri opintojakson esimerkkitietokantaan http://netisto.fi/oppaat/tietokannat/?id=03, että yli miljoonan asukkaan kotikaupunkeja ei voi lisätä INSERT INTO -lauseella cities-tauluun.
Palautuksesta tulee ilmetä, että että yli miljoonan asukkaan kotikaupunkien lisäys ei onnistu.
![](H8/T1A.png)
![](H8/T1B.png)
Poista luomasi triggeri sen toiminnan testauksen jälkeen.
```
drop trigger ylimiljoona;
```
## Tehtävä 2 [2p]
Luo transaktio jossa opintojakson esimerkkitietokannan http://netisto.fi/oppaat/tietokannat/?id=03
1) cities-tauluun lisätään kaksi uutta kaupunkia yhdellä INSERT INTO -lauseella JA
2) students-tauluun lisätään kaksi uutta opiskelijaa yhdellä INSERT INTO -lauseella, joiden kotikuntana on jompikumpi kohdassa A) lisätyistä kotikaupungeista
Palautuksesta tulee ilmetä, että kaikki em. transaktioon määritellyt lisäykset onnistuivat.
```
MariaDB [student_db]> BEGIN;
Query OK, 0 rows affected (0.000 sec)
MariaDB [student_db]> INSERT INTO cities(cityname,population) VALUES ("Rovaniemi",50000),("Jyväskylä",51000);
Query OK, 2 rows affected (0.000 sec)
Records: 2 Duplicates: 0 Warnings: 0
MariaDB [student_db]> INSERT INTO students VALUES (2009,"Kiljunen","Kimmo","2000-01-01","Vihreä",100,0,(SELECT cityid from cities WHERE cityname="Rovaniemi")),(2010,"Rapia","Reino","1930-12-01","Musta",100000,40,(SELECT cityid from cities WHERE cityname="Jyväskylä"));
Query OK, 2 rows affected (0.000 sec)
Records: 2 Duplicates: 0 Warnings: 0
MariaDB [student_db]> commit;
Query OK, 0 rows affected (0.002 sec)
MariaDB [student_db]> SELECT lastname,firstname,cityname AS hometown
-> FROM students
-> INNER JOIN cities
-> ON students.hometown = cities.cityid;
+----------+-----------+-----------+
| lastname | firstname | hometown |
+----------+-----------+-----------+
| Guru | Ken | Turku |
| Saurus | Tino | Turku |
| Tiainen | Sini | Turku |
| Rahainen | Muu | Tampere |
| Alainen | Kim | Tampere |
| Vainio | Elo | Lahti |
| Vainio | Vilja | Lahti |
| Kiljunen | Kimmo | Rovaniemi |
| Rapia | Reino | Jyväskylä |
+----------+-----------+-----------+
9 rows in set (0.000 sec)
```
## Tehtävä 3 [2p]
Luo transaktio jossa opintojakson esimerkkitietokannan http://netisto.fi/oppaat/tietokannat/?id=03
1) cities-tauluun lisätään kaksi uutta kaupunkia yhdellä INSERT INTO -lauseella JA
2) students-tauluun lisätään kaksi uutta opiskelijaa yhdellä INSERT INTO -lauseella, joiden studentID on virheellisesti sama
Palautuksesta tulee ilmetä, että kaupunkien lisäys onnistui (transaktiosta huolimatta) mutta opiskelijoiden lisäys ei onnistunut.
```
MariaDB [student_db]> BEGIN;
Query OK, 0 rows affected (0.000 sec)
MariaDB [student_db]> INSERT INTO cities(cityname,population) VALUES ("Inari",52000),("Kajaani",53000);
Query OK, 2 rows affected (0.000 sec)
Records: 2 Duplicates: 0 Warnings: 0
MariaDB [student_db]> INSERT INTO students VALUES (2011,"Pajunen","Pekka","2000-01-01","Vihreä",100,0,(SELECT cityid from cities WHERE cityname="Inari")),(2011,"Koivunen","Kalle","1950-12-01","Musta",100000,40,(SELECT cityid from cities WHERE cityname="Kajaani"));
ERROR 1062 (23000): Duplicate entry '2011' for key 'PRIMARY'
MariaDB [student_db]> COMMIT;
Query OK, 0 rows affected (0.002 sec)
MariaDB [student_db]> SELECT * FROM cities;
+--------+-----------+------------+
| cityID | cityname | population |
+--------+-----------+------------+
| 1 | Turku | 190000 |
| 2 | Tampere | 230000 |
| 3 | Lahti | 120000 |
| 17 | Rovaniemi | 50000 |
| 18 | Jyväskylä | 51000 |
| 19 | Inari | 52000 |
| 20 | Kajaani | 53000 |
+--------+-----------+------------+
7 rows in set (0.000 sec)
MariaDB [student_db]> SELECT * FROM students;
+-----------+----------+-----------+------------+----------+-----------+---------+----------+
| studentID | lastname | firstname | birthdate | eyecolor | incomes | taxrate | hometown |
+-----------+----------+-----------+------------+----------+-----------+---------+----------+
| 2001 | Guru | Ken | 2001-11-11 | Ruskea | 12010.12 | 5.10 | 1 |
| 2002 | Saurus | Tino | 2002-11-11 | Ruskea | 14010.22 | 6.20 | 1 |
| 2003 | Tiainen | Sini | 2003-11-11 | Sininen | 16010.32 | 7.30 | 1 |
| 2004 | Vainio | Vilja | 2004-11-11 | Sininen | 0.00 | 0.00 | 3 |
| 2005 | Vainio | Elo | 2005-11-11 | Sininen | 0.00 | 0.00 | 3 |
| 2006 | Rahainen | Muu | 2006-11-11 | Harmaa | 13010.12 | 5.80 | 2 |
| 2007 | Alainen | Kim | 2007-11-11 | NULL | 18010.12 | 8.80 | 2 |
| 2008 | Ana | Ruut | 2008-11-11 | NULL | 20010.12 | 9.90 | NULL |
| 2009 | Kiljunen | Kimmo | 2000-01-01 | Vihreä | 100.00 | 0.00 | 17 |
| 2010 | Rapia | Reino | 1930-12-01 | Musta | 100000.00 | 40.00 | 18 |
+-----------+----------+-----------+------------+----------+-----------+---------+----------+
10 rows in set (0.000 sec)
```
## Tehtävä 4 [4p]
Luo edellisen tehtävän transaktion yhteyteen sellainen sp_fail()-niminen tallennettu proseduuri (stored procedure), jota kutsuessa kaikki INSERT INTO-lauseet peruutetaan (ROLLBACK), jos yhdenkin suoritus epäonnistuu jostakin syystä. Jos kaikki INSERT INTO -lauseet ovat suoritettavissa, transaktio hyväksytään kokonaisuudessaan (COMMIT).
Käytä luomaasi tallennettua proseduuria kutsumalla sitä CALL sp_fail;
Palautuksesta tulee ilmetä, että kaupunkienkaan lisäys ei onnistunut, jos jonkun opiskelijan lisäys ei onnistunut.
Tähän tehtävään ei löydy opintojakson puitteissa tarjotusta materiaalista juurikaan apua. Tehtävän ratkaisua voit etsiä hakusanoin "mysql stored procedures" tai tarkemmin vaikkapa seuraavista lähteistä: [Lähde 1](https://stackoverflow.com/questions/19905900/mysql-transaction-roll-back-on-any-exception/19908197), [Lähde 2](http://sqlfiddle.com/#!2/8ea00/1) tai [Lähde 3](https://www.mysqltutorial.org/listing-stored-procedures-in-mysql-database.aspx/)
(Suoraan stackoverflowissa olevan esimerkin pohjalta):
![](H8/T4.png)
```
MariaDB [student_db]> CALL `sp_fail`;
Query OK, 2 rows affected (0.009 sec)
MariaDB [student_db]> SELECT * FROM cities;
+--------+-----------+------------+
| cityID | cityname | population |
+--------+-----------+------------+
| 1 | Turku | 190000 |
| 2 | Tampere | 230000 |
| 3 | Lahti | 120000 |
| 17 | Rovaniemi | 50000 |
| 18 | Jyväskylä | 51000 |
| 19 | Inari | 52000 |
| 20 | Kajaani | 53000 |
+--------+-----------+------------+
7 rows in set (0.000 sec)
MariaDB [student_db]> SELECT * FROM students;
+-----------+----------+-----------+------------+----------+-----------+---------+----------+
| studentID | lastname | firstname | birthdate | eyecolor | incomes | taxrate | hometown |
+-----------+----------+-----------+------------+----------+-----------+---------+----------+
| 2001 | Guru | Ken | 2001-11-11 | Ruskea | 12010.12 | 5.10 | 1 |
| 2002 | Saurus | Tino | 2002-11-11 | Ruskea | 14010.22 | 6.20 | 1 |
| 2003 | Tiainen | Sini | 2003-11-11 | Sininen | 16010.32 | 7.30 | 1 |
| 2004 | Vainio | Vilja | 2004-11-11 | Sininen | 0.00 | 0.00 | 3 |
| 2005 | Vainio | Elo | 2005-11-11 | Sininen | 0.00 | 0.00 | 3 |
| 2006 | Rahainen | Muu | 2006-11-11 | Harmaa | 13010.12 | 5.80 | 2 |
| 2007 | Alainen | Kim | 2007-11-11 | NULL | 18010.12 | 8.80 | 2 |
| 2008 | Ana | Ruut | 2008-11-11 | NULL | 20010.12 | 9.90 | NULL |
| 2009 | Kiljunen | Kimmo | 2000-01-01 | Vihreä | 100.00 | 0.00 | 17 |
| 2010 | Rapia | Reino | 1930-12-01 | Musta | 100000.00 | 40.00 | 18 |
+-----------+----------+-----------+------------+----------+-----------+---------+----------+
10 rows in set (0.000 sec)
```
## Tehtävä 5 [6p]
A) Luo kuvitteellista keskustelufoorumi-ohjemiston viestien tallentamista varten tietokannan taulu, jossa perusavaimena on juokseva numero (kokonaisluku). Muita kenttiä tulee olla ainakin viestin otsikkoa, kirjoittajaa ja sisältöä varten. Myös viestin lisäysajankohta tulee tallentaa. Lisäksi tulee olla INTEGER-tyyppinen "parent"-kenttä, joka kertoo numerollaan, minkä viestin vastaus se mahdollisesti on. "Parent"-kentän arvo asetetaan NULL, jos viesti on viestiketjun avaava viesti. "Parent"-kenttä tulee olla viiteavaimena taulun perusavaimelle.
![](H8/T5A.png)
```
MariaDB [yhdentaulunfoorumi]> DESC viestit;
+---------------+--------------+------+-----+---------------------+-------------------------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------------------+-------------------------------+
| viestiID | int(11) | NO | PRI | NULL | auto_increment |
| otsikko | varchar(255) | NO | | NULL | |
| kirjoittaja | varchar(30) | NO | | NULL | |
| viesti | text | NO | | NULL | |
| kirjoitusaika | timestamp | NO | | current_timestamp() | on update current_timestamp() | <-- päivittyy kun riviä muutetaan,
| parent | int(11) | YES | MUL | NULL | | ei hyvä jos foorumilla
+---------------+--------------+------+-----+---------------------+-------------------------------+ muokkausominaisuus
6 rows in set (0.009 sec)
```
B) Lisää tauluun sisältöä siten, että viestejä on vähintään kolmella tasolla kuten oheisessa esimerkissä. On siis keskustelun avaavia viestejä, niiden vastauksia ja vastauksien vastauksia. Lisättyjen viesttien ei tietenkään tarvitse olla oheisen esimerkin mukaisia
- Eka viesti
- Toka viesti
- Koka viesti
- Neka viesti
- Kasi viesti
- Ysi viesti
- Vika viesti
- Kuka viesti
- Seka viesti
```
INSERT INTO viestit(otsikko,kirjoittaja,viesti,parent)
VALUES
("Eka viesti","Janne","Tämä on testi #1",NULL),
("Eka vastaus","Janne","Tämä on testi #2",1),
("Tokaan viestiin 1. vastaus ","Janne","Tämä on testi #3",2),
("Tokaan viestiin 2. vastaus","Janne","Tämä on testi #4",2),
("Toka vastaus","Janne","Tämä on testi #5",1),
("Kolmannnen 1. vastaus","Janne","Tämä on testi #6",5),
("Kolmannnen 2. vastaus","Janne","Tämä on testi #7",5),
("Tokaan viestiin 3. vastaus","Janne","Tämä on testi #8",2),
("Tokaan viestiin 4. vastaus","Janne","Tämä on testi #9",2)
```
```
MariaDB [yhdentaulunfoorumi]> SELECT * FROM viestit;
+----------+-----------------------------+-------------+------------------+---------------------+--------+
| viestiID | otsikko | kirjoittaja | viesti | kirjoitusaika | parent |
+----------+-----------------------------+-------------+------------------+---------------------+--------+
| 1 | Eka viesti | Janne | Tämä on testi #1 | 2022-03-13 15:13:12 | NULL |
| 2 | Eka vastaus | Janne | Tämä on testi #2 | 2022-03-13 15:13:12 | 1 |
| 3 | Tokaan viestiin 1. vastaus | Janne | Tämä on testi #3 | 2022-03-13 15:13:12 | 2 |
| 4 | Tokaan viestiin 2. vastaus | Janne | Tämä on testi #4 | 2022-03-13 15:13:12 | 2 |
| 5 | Toka vastaus | Janne | Tämä on testi #5 | 2022-03-13 15:13:12 | 1 |
| 6 | Kolmannnen 1. vastaus | Janne | Tämä on testi #6 | 2022-03-13 15:13:12 | 5 |
| 7 | Kolmannnen 2. vastaus | Janne | Tämä on testi #7 | 2022-03-13 15:13:12 | 5 |
| 8 | Tokaan viestiin 3. vastaus | Janne | Tämä on testi #8 | 2022-03-13 15:13:12 | 2 |
| 9 | Tokaan viestiin 4. vastaus | Janne | Tämä on testi #9 | 2022-03-13 15:13:12 | 2 |
+----------+-----------------------------+-------------+------------------+---------------------+--------+
9 rows in set (0.000 sec)
```
C) Tee SQL-kysely, jolla haetaan kaikki ensimmäisen tason viestien vastaukset.
```
MariaDB [yhdentaulunfoorumi]> SELECT * FROM viestit WHERE parent in (SELECT viestiID from viestit WHERE parent IS NULL);
+----------+--------------+-------------+------------------+---------------------+--------+
| viestiID | otsikko | kirjoittaja | viesti | kirjoitusaika | parent |
+----------+--------------+-------------+------------------+---------------------+--------+
| 2 | Eka vastaus | Janne | Tämä on testi #2 | 2022-03-13 15:13:12 | 1 |
| 5 | Toka vastaus | Janne | Tämä on testi #5 | 2022-03-13 15:13:12 | 1 |
+----------+--------------+-------------+------------------+---------------------+--------+
2 rows in set (0.000 sec)
```
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment