mysql è un software gratuito incluso in vari pacchetti di installazione: Easyphp, wamp, xampp, sia per Windows che per Linux.
ciascun pacchetto software include: Apache server, MySQL database e il supporto completo di PHP come strumento di sviluppo per siti web.
Dopo aver scaricato il file, procedere all'installazione. Durante l'installazione viene chiesto il percorso in cui memorizzare l'applicazione, se si accetta la scelta di default, viene creata una sottocartella nella cartella Programmi. Si eviti di accettare questa scelta perchè in alcune installazioni la cartella programmi è protetta e non si riuscirà a salvare le pagine del sito.
All'interno della cartella di installazione vengono create le cartelle MySql, per contenere il DBMS relazionale, e www, per memorizzare le pagine del sito web.
MySQL può essere usato tramite i comandi immessi dal prompt del DOS oppure tramite un'interfaccia grafica o, ancora, in una pagina web in cui i comandi sono interpretati dal lato server.
In una finestra dos, posizionarsi nella cartella contenente il server MySql, ad es:
cd C:\Programmi\EasyPHPx-x\mysql\bin
e collegarsi al server MySql con il seguente comando:
mysql -u root.
In risposta a questa richiesta il programma, dopo aver ricordato che i comandi devono essere terminati con il carattere punto e virgola, mostra il prompt del client MySql:
mysql>
Il richiamo del server MySql avviene con un comando che specifica:
cioè:
mysql -h <indirizzo server> -u <nome utente> -p
In questo caso, dopo aver premuto invio verrà richiesta la password.
Il comando: mysql -u root è ammesso quando il server è in esecuzione sullo stesso computer dove si esegue il client e ci si vuole collegare al server in modalità amministratore.
Per la gestione di un magazzino e l'emissione di uno scontrino le entità da modellare sono:
il grado della relazione tra le due entità è N:N, perchè un articolo può essere acquistato da più clienti e un cliente può acquistare più articoli.
Tra le due tabelle, quindi, ci deve essere una terza tabella.
Scontrino | dettagliScontrino | Articoli | ||
IDVendita | 1 —— N | IDVendita | Descrizione | |
Data | IDArticolo | N —— 1 | IDArticolo | |
Cliente | Qta | QtaScorta | ||
Prezzo |
Si deve notare che la proprietà Quantità di articoli acquistati fa parte della relazione tra le due tabelle.
La query di Creazione del data base:
mysql> create database Magazzino;
Con questa operazione si è creato il database sul disco. Se il database esiste, la creazione ne distrugge il contenuto. Il server MySQL risponde:
Query OK, 1 row affected ...
Accesso al database: Il comando use seleziona il database.
mysql> use Magazzino;
Il server MySQL risponde:
Database changed
Da notare che i comandi possono occupare anche più righe e, comunque, nell'ultima riga si deve indicare la terminazione del comando tramite il punto e virgola.
Per usare MySql tramite un'interfaccia grafica scaricare
MySQL Query Browser.
Scegliere di scaricare la versione compressa e decomprimerla sul disco C:
Nella cartella decompressa fare doppio clic sul programma "MYSQL Query Browser"
Creare un account per un utente sul data base Magazzino:
mysql> grant all on Magazzino.*
-> to donDiego@localhost
-> identified by 'zorro';
Query OK, 0 rows affected (0.53 sec)
Usare le credenziali dell'utente appena creato per completare i campi richiesti da MYSQL Query Browser e collegarsi al server MySql per interrogare il data base "Magazzino".
Per una introduzione all'utilizzo del programma consultare la guida.
Sintassi per creare una tabella:
CREATE TABLE Nome della Tabella(
<dichiarazione campo1>,
[<dichiarazione campoN>,…]
);
dove <Nome della Tabella> è l'identificativo assegnato alla tabella e tra parentesi è specificata la dichiarazione dei campi, separati da virgola, consistente nel nome assegnato al campo, dal Tipo del campo (intero, stringa, …), ammissibilità dei valori NULL (NOT NULL = campo obbligatorio), Indicizzazione del campo (cioè se chiave), valore iniziale e, se il campo è chiave, modalità per il calcolo del valore successivo.
mysql> create table Scontrino (
-> IDVendita int not null auto_increment primary key,
-> Data date,
-> Cliente varchar(20)
-> );
Il server MySQL risponde:
Query OK, 0 rows affected (0.22 sec)
Il campo IDVendita è di tipo intero (int), assume sempre un valore (not null), è un contatore (auto_increment) ed è la chiave primaria della tabella.
mysql> create table Articoli (
-> Descrizione varchar(20),
-> IDArticolo int not null auto_increment primary key,
-> QtaScorta int,
-> Prezzo decimal(5,2)
-> );
Il server MySQL risponde:
Query OK, 0 rows affected (0.13 sec)
Il tipo decimal(5,2) assegna 5 cifre in totale per rappresentare il numero, di cui 2 cifre sono decimali, cioè i valori che si possono assegnare al campo Prezzo sono compresi tra -999.99 e 999.99.
mysql> create table dettagli (
-> IDVendita int,
-> IDArticolo int,
-> Qta int,
-> Primary key (IDVendita, IDArticolo),
-> Foreign key (IDVendita) references Scontrino(IDVendita),
-> Foreign key (IDArticolo) references Articoli(IDArticolo),
-> Check Qta>0
-> );
Il server MySQL risponde:
Query OK, 0 rows affected (0.80 sec)
Avendo specificato che i campi IDVendita e IDArticolo sono chiavi esterne, si è imposto il rispetto dell'integrità referenziale.
Quindi non sarà possibile aggiungere record in questa tabella Dettagli se non esiste il record associato nella tabella Scontrino e quello nella tabella Articoli.
Con Check Qta>0 si è imposto il vincolo sull'immissione di valori positivi nel campo Qta.
Il comando per esaminare la struttura di una tabella è:
describe Articoli;
che mostra la tabella nella seguente forma:
+-------------+--------------+------+-----+---------+----------+ | Field | Type | Null | Key | Default | Extra | +-------------+--------------+------+-----+---------+----------+ | Descrizione | varchar(20) | YES | | NULL | | | IDArticolo | int(11) | NO | PRI | NULL | auto_inc | | QtaScorta | int(11) | YES | | NULL | | | Prezzo | decimal(5,2) | YES | | NULL | | +-------------+--------------+------+-----+---------+----------+ 4 rows in set (0.02 sec)
Aggiungere un campo alla tabella
Dopo aver creato la tabella per modificarne la struttura bisogna usare il comando
alter table
Ad esempio, per aggiungere un campo alla tabella Articoli che permetta di associare l'articolo ad un certo reparto si aggiunga il campo reparto di tipo intero:
mysql> alter table Articoli
-> add reparto int;
Il server MySQL risponde:
Query OK, 0 rows affected (0.31 sec)
Records: 0 Duplicati: 0 Avvertimenti: 0
Il campo reparto è stato dichiarato di tipo intero perchè i valori assegnati a questo campo rappresentano un codice numerico che, in seguito, si potrà collegare alla chiave primaria di una tabella contenente i nomi dei reparti.
Eliminare un campo:
alter table NomeTabella drop column NomeCampo
Modificare il nome, il tipo di un campo o entrambi
Sintassi per modificare il nome di un campo della tabella:
alter table NomeTabella change
NomeCampo Nuova dichiarazione campo;
la parte in cui si deve specificare la dichiarazione del campo è composta dal nuovo nome e dal nuovo tipo del campo.
Eliminare una tabella
Drop Table Nome Tabella
Se una tabella è collegata ad un'altra tabella, la cancellazione potrebbe violare l'integrità referenziale. In questo caso il comando di eliminazione tabella diventa:
Drop Table Nome Tabella Restrict
La specificazione restrict assicura che la cancellazione della tabella avviene se non esistono record associati nella tabella secondaria.
Il comando
Drop Table Nome Tabella cascade
elimina la tabella e i record associati.
inserire record in una tabella
insert into tabella (elenco campi)
values (elenco valori);
l'elenco dei valori viene assegnato ai campi della tabella nello stesso ordine in cui compaiono. Ai campi omessi viene assegnato il valore NULL.
Ad esempio per aggiungere un record alla tabella Articoli:
mysql> insert into Articoli
-> (Descrizione, QtaScorta, Prezzo, reparto)
-> values ('Dentifricio', 120, 1.95, 1);
Query OK, 1 row affected (0.06 sec)
Per leggere il contenuto della tabella:
select * from Articoli;
+-------------+------------+-----------+--------+---------+ | Descrizione | IDArticolo | QtaScorta | Prezzo | reparto | +-------------+------------+-----------+--------+---------+ | Dentifricio | 1 | 120 | 1.95 | 1 | +-------------+------------+-----------+--------+---------+ 1 row in set (0.00 sec)
Si noti che il valore al campo IDArticolo è stato assegnato automaticamente.
Il vincolo dell'integrità referenziale esige che la tabella Articoli contenga i prodotti che possono comparire in uno scontrino prima ancora di emettere uno scontrino. Quindi, come in una situazione reale, si inseriscano altri prodotti nella tabella Articoli per simulare un carico di magazzino.
Un altro modo per inserire i record in una tabella consiste nel creare un file di testo nella cartella mysql\bin.
Bisogna scrivere un record per linea e separare i valori dei campi con una tabulazione.
Ad esempio, tramite il blocco note creare un file con nome: articoli.txt e scrivere alcuni record relativi a prodotti da inserire nella tabella.
In corrispondenza di un campo chiave generato automaticamente o per un campo a cui non si assegna un valore scrivere \N (con N maiuscola. \N significa NULL). Ad esempio, se il file contiene le seguenti righe:
Saponetta \N 80 0.60 1 Passata di Pomodoro \N 1000 1.20 2 Shampoo \N 100 2.25 1 dado vegetale \N 250 0.90 2 olio di oliva \N 20 4.50 2 nutella 200g \N 80 2.20 3 miele acacia \N 60 4.80 3 marmellata \N 75 2.30 3 burro \N 120 1.30 4 formaggio \N 5.30 4
Per trasferire i record dal file di testo alla tabella Articoli usare il comando:
mysql> load data local infile 'Articoli.txt' into table Articoli
-> lines terminated by '\r\n';
La specifica lines terminated by '\r\n'; indica che una linea del file generata con il blocco note è terminata con i caratteri \r (linefeed: avanza di una riga) e \n (carriage return: vai a inizio riga).
Per leggere tutti record contenuti nella tabella articoli, il comando:
SELECT * FROM Articoli;
produce il seguente risultato:
+---------------------+------------+-----------+--------+---------+ | Descrizione | IDArticolo | QtaScorta | Prezzo | reparto | +---------------------+------------+-----------+--------+---------+ | Dentifricio | 1 | 120 | 1.95 | 1 | | Saponetta | 2 | 80 | 0.60 | 1 | | Passata di Pomodoro | 3 | 100 | 2.00 | 2 | | Shampoo | 4 | 100 | 2.25 | 1 | | dado vegetale | 5 | 250 | 0.90 | 2 | | olio di oliva | 6 | 20 | 4.50 | 2 | | nutella 200g | 7 | 80 | 2.20 | 3 | | miele acacia | 8 | 60 | 4.80 | 3 | | marmellata | 9 | 75 | 2.30 | 3 | | burro | 10 | 120 | 1.30 | 4 | | formaggio | 11 | 5 | 4.00 | 4 | +---------------------+------------+-----------+--------+---------+ 11 rows in set (0.00 sec)
cambiare il valore di un campo (comando update).
Ad esempio per correggere il valore
del campo QtaScorta, nel secondo record, da 1000 a 100:
mysql> update Articoli set QtaScorta=100 where IDArticolo=3;
Query OK, 1 row affected (0.98 sec)
Righe riconosciute: 1 Cambiate: 1 Warnings: 0
La sintassi per modificare i valori dei campi di una tabella è:
UPDATE Nome della Tabella
SET Campo = Valore
[Campo = Valore]
WHERE Condizione
Cancellare record da una tabella.
La sintassi per modificare i valori dei campi di una tabella è:
DELETE FROM Nome della Tabella
WHERE Condizione
Una Query è l'operazione di ricerca di informazioni all'interno della base dati. Il risultato di una query è una tabella temporanea.
select Descrizione, Prezzo from Articoli;
mostra solo due campi della tabella: Descrizione e Prezzo.
+---------------------+--------+ | Descrizione | Prezzo | +---------------------+--------+ | Dentifricio | 1.95 | | Saponetta | 0.60 | | Passata di Pomodoro | 2.00 | | Shampoo | 2.25 | | dado vegetale | 0.90 | | olio di oliva | 4.50 | | nutella 200g | 2.20 | | miele acacia | 4.80 | | marmellata | 2.30 | | burro | 1.30 | | formaggio | 4.00 | +---------------------+--------+ 11 rows in set (0.50 sec)
Normalmente il risultato di una query è costituito da tutti i record che soddisfano la condizione di ricerca, quindi alcune righe potrebbero essere duplicate, ad esempio se, per consultare i reparti in cui è suddiviso il magazzino, si esegue la query
select reparto from Articoli;
si ottengono i numeri di reparto di tutte le righe della tabella:
+---------+ | reparto | +---------+ | 1 | | 1 | | 2 | | 1 | | 2 | | 2 | | 3 | | 3 | | 3 | | 4 | | 4 | +---------+ 11 rows in set (0.00 sec)
Per ridurre il risultato della query ed evitare, quindi, di ripetere i record che hanno lo stesso valore, aggiungere
la specifica distinct alla query:
select distinct reparto from Articoli;
+---------+ | reparto | +---------+ | 1 | | 2 | | 3 | | 4 | +---------+ 4 rows in set (0.05 sec)
La seguente Query:
SELECT Descrizione, Prezzo FROM Articoli ORDER BY Prezzo;
fornisce i valori dei campi Descrizione e Prezzo di tutti i record della tabella.
La clausola ORDER BY specifica il nome del campo da usare per ordinare i record, per default l'ordinamento avviene in senso crescente. Se si desidera ottenere il risultato in ordine decrescente si deve aggiungere DESC (descending):
SELECT Descrizione, Prezzo FROM Articoli ORDER BY Prezzo DESC;
L'ordinamento può essere applicato a tutti i campi della query che si desidera e per ciascun campo si può scegliere la direzione dell'ordinamento.
La seguente query produce una tabella di record ordinati per Prezzo in senso crescente e, in corrispondenza
di Prezzo uguale, i recordo sono ordinati per Descrizione decrescente:
mysql> SELECT Descrizione, Prezzo FROM Articoli
-> ORDER BY Prezzo, Descrizione DESC;
Notare che per il campo Prezzo non è stata specificata la direzione dell'ordinamento, quindi si assume quella di default: crescente, mentre DESC si applica solo al campo Descrizione.
La query:
select Descrizione, reparto, Prezzo*0.8
as scontato from Articoli;
mostra i campi Descrizione, reparto e il risultato del calcolo dell'80% del prezzo in una colonna denominata scontato.
+---------------------+---------+----------+ | Descrizione | reparto | scontato | +---------------------+---------+----------+ | Dentifricio | 1 | 1.5600 | | Saponetta | 1 | 0.4800 | | Passata di Pomodoro | 2 | 1.6000 | | Shampoo | 1 | 1.8000 | | dado vegetale | 2 | 0.7200 | | olio di oliva | 2 | 3.6000 | | nutella 200g | 3 | 1.7600 | | miele acacia | 3 | 3.8400 | | marmellata | 3 | 1.8400 | | burro | 4 | 1.0400 | | formaggio | 4 | 3.2000 | +---------------------+---------+----------+ 11 rows in set (0.06 sec)
Gli operatori Like e Not Like svolgono il confronto tra stringhe, impiegando i caratteri jolly. Il segno di sottolineatura indica un carattere qualsiasi, il segno di percentuale indica un insieme di caratteri qualsiasi.
Ad esempio per cercare le Descrizioni di articoli che iniziano con D:
select * from Articoli where Descrizione like "D%";
+---------------+------------+-----------+--------+---------+ | Descrizione | IDArticolo | QtaScorta | Prezzo | reparto | +---------------+------------+-----------+--------+---------+ | Dentifricio | 1 | 120 | 1.95 | 1 | | dado vegetale | 5 | 250 | 0.90 | 2 | +---------------+------------+-----------+--------+---------+ 2 rows in set (0.03 sec)
per trovare le Descrizioni di articoli il cui nome è formato da 5 lettere:
select * from Articoli where Descrizione like "_____";
Creare la tabella Reparti
mysql> create table reparti(
-> IDrep int not null auto_increment primary key,
-> Nome varchar(20)
-> );
Query OK, 0 rows affected (0.27 sec)
Assegnare i valori ai record:
mysql> insert into Reparti (IDrep, Nome) values (1, 'igiene');
Query OK, 1 row affected (0.05 sec)
mysql> insert into Reparti (IDrep, Nome) values (2, 'condimenti');
Query OK, 1 row affected (0.02 sec)
mysql> insert into Reparti (IDrep, Nome) values (3, 'colazione');
Query OK, 1 row affected (0.01 sec)
mysql> insert into Reparti (IDrep, Nome) values (4, 'formaggi');
Query OK, 1 row affected (0.02 sec)
Visualizzare l'elenco dei prodotti di magazzino con il nome, anzichè il codice, del reparto:
mysql> select descrizione, prezzo, nome
-> from articoli, reparti
-> where Articoli.reparto=Reparti.IDrep;
+---------------------+--------+------------+ | descrizione | prezzo | nome | +---------------------+--------+------------+ | Dentifricio | 1.95 | igiene | | Saponetta | 0.60 | igiene | | Shampoo | 2.25 | igiene | | Passata di Pomodoro | 2.00 | condimenti | | dado vegetale | 0.90 | condimenti | | olio di oliva | 4.50 | condimenti | | nutella 200g | 2.20 | colazione | | miele acacia | 4.80 | colazione | | marmellata | 2.30 | colazione | | burro | 1.30 | formaggi | | formaggio | 4.00 | formaggi | +---------------------+--------+------------+ 11 rows in set (0.13 sec)
Si abbiano le due tabelle:
Clienti | Fornitori | |
IDCliente | IDFornitore | |
Nome | Nome | |
Indirizzo | Indirizzo | |
L'operazione di Unione tra le due tabelle fornisce i record appartenenti alla tabella Clienti o alla tabella Fornitori o a entrambe le tabelle.
Sia x un record dell'unione:
x ∈ (Clienti ∪ Fornitori) ↔ x ∈ Clienti OR x ∈ Fornitori
(Select Nome from Clienti)
UNION
(Select Nome from Fornitori)
L'operazione di intersezione tra le due tabelle fornisce i record appartenenti contemporaneamente sia alla tabella Clienti che alla tabella Fornitori:
Sia x un record dell'intersezione:
x ∈ (Clienti ∩ Fornitori) ↔ x ∈ Clienti and x ∈ Fornitori(Select Nome from Clienti)
INTERSECT
(Select Nome from Fornitori)
L'operazione di complemento della tabella Clienti rispetto alla tabella Fornitori fornisce i record appartenenti alla tabella Clienti che appartengono anche alla tabella Fornitori:
Sia x un record del complemento:
x ∈ (Clienti - Fornitori) ↔ x ∈ Clienti and x ∉ Fornitori(Select Nome from Clienti)
MINUS
(Select Nome from Fornitori)
Le funzioni di aggregazione sono:
Esempi:
mysql> select count(IDArticolo)
-> from articoli;
+-------------------+ | count(IDArticolo) | +-------------------+ | 11 | +-------------------+ 1 row in set (0.00 sec)
mysql> select count(IDArticolo)
-> from articoli
-> where reparto=1;
+-------------------+ | count(IDArticolo) | +-------------------+ | 3 | +-------------------+ 1 row in set (0.00 sec)
mysql> select Descrizione, min(prezzo) from articoli;
+-------------+-------------+ | Descrizione | min(prezzo) | +-------------+-------------+ | Dentifricio | 0.60 | +-------------+-------------+ 1 row in set (0.03 sec)
mysql> select avg(prezzo) from articoli
-> where reparto=1;
+-------------+ | avg(prezzo) | +-------------+ | 1.600000 | +-------------+ 1 row in set (0.01 sec)
I risultati di una funzione di aggregazione applicata ad una query di selezione possono essere ulteriormente trattati mediante le operazioni di raggruppamento:
Esempi:
mysql> select reparto, avg(prezzo) from articoli
-> group by reparto;
+---------+-------------+ | reparto | avg(prezzo) | +---------+-------------+ | 1 | 1.600000 | | 2 | 2.466667 | | 3 | 3.100000 | | 4 | 2.650000 | +---------+-------------+ 4 rows in set (0.00 sec)
mysql> select Descrizione, QtaScorta, reparto from Articoli
-> group by reparto having QtaScorta<=100;
+---------------------+-----------+---------+ | Descrizione | QtaScorta | reparto | +---------------------+-----------+---------+ | Passata di Pomodoro | 100 | 2 | | nutella 200g | 80 | 3 | +---------------------+-----------+---------+ 2 rows in set (0.00 sec)
Si consideri la tabella Articoli la cui chiave primaria è IDArticolo e la tabella dettagli
in cui il campo IDArticolo è chiave secondaria. Tra le due tabelle esiste una relazione 1:N.
Sono associati a un record della tabella Articoli i record della tabella dettagli la cui chiave secondaria
ha lo stesso valore della chiave primaria.
Un'interrogazione che preleva record da tabelle collegate deve specificare il tipo di join tra le due tabelle:
Si hanno 3 join:
mysql> select Descrizione, Prezzo FROM Articoli
-> join dettagli ON Articoli.IDArticolo=dettagli.IDArticolo;
+---------------------+--------+ | Descrizione | Prezzo | +---------------------+--------+ | Passata di Pomodoro | 2.00 | | dado vegetale | 0.90 | | nutella 200g | 2.20 | +---------------------+--------+ 3 rows in set (0.00 sec)
Il risultato è costituito dalle righe di entrambe le tabelle che hanno lo stesso valore nei campi collegati.
mysql> select Descrizione, Prezzo, Qta FROM Articoli
-> left join dettagli
-> ON Articoli.IDArticolo=dettagli.IDArticolo;
+---------------------+--------+------+ | Descrizione | Prezzo | Qta | +---------------------+--------+------+ | Dentifricio | 1.95 | NULL | | Saponetta | 0.60 | NULL | | Passata di Pomodoro | 2.00 | 2 | | Shampoo | 2.25 | NULL | | dado vegetale | 0.90 | 4 | | olio di oliva | 4.50 | NULL | | nutella 200g | 2.20 | 6 | | miele acacia | 4.80 | NULL | | marmellata | 2.30 | NULL | | burro | 1.30 | NULL | | formaggio | 4.00 | NULL | +---------------------+--------+------+ 11 rows in set (0.00 sec)
Il risultato è costituito da tutti i record della tabella Articoli. Quando manca un record nella tabella collegata viene fornito il valore NULL per il campo Qta.
mysql> select Descrizione, Prezzo, Qta FROM Articoli
-> right join dettagli
-> ON Articoli.IDArticolo=dettagli.IDArticolo;
+---------------------+--------+------+ | Descrizione | Prezzo | Qta | +---------------------+--------+------+ | Passata di Pomodoro | 2.00 | 2 | | dado vegetale | 0.90 | 4 | | nutella 200g | 2.20 | 6 | +---------------------+--------+------+ 3 rows in set (0.00 sec)
Il risultato è costituito da tutti i record della tabella dettagli. Se nella tabella Articoli mancasse un record collegato, per quel campo sarebbe stato specificato il valore NULL.
La condizione che devono soddisfare i campi collegati deve essere specificata con la clausola ON.
Una tabella può essere riferita mediante un nome alternativo specificato dopo la clausola AS. Esempio:
SELECT * FROM Articoli AS A WHERE A.QtaScorta>100;
La tabella Articoli viene identificata con l'alias A
Using. Nel caso particolare in cui i due campi collegati hanno lo stesso nome si può omettere la condizione ON specificando il nome del campo, racchiuso tra parentesi, dopo USING, come nel seguente esempio:
mysql> SELECT Descrizione, Prezzo, Qta
-> FROM Articoli
-> JOIN dettagli
-> USING (IDArticolo);
+---------------------+--------+------+ | Descrizione | Prezzo | Qta | +---------------------+--------+------+ | Passata di Pomodoro | 2.00 | 2 | | dado vegetale | 0.90 | 4 | | nutella 200g | 2.20 | 6 | +---------------------+--------+------+ 3 rows in set (0.00 sec)
Emettere uno scontrino.
Registrare un Cliente nella tabella "Scontrino", dando allo scontrino il numero IDVendita=1:
mysql> insert into scontrino
-> (IDVendita, Data, Cliente)
-> values
-> (1, '2009-06-25', 'Rossi Mario');
Query OK, 1 row affected (0.02 sec)
Sullo scontrino numero 1 simulare l'acquisto di 3 prodotti:
insert into dettagli(IDVendita, IDArticolo, Qta)values (1, 3, 2);
insert into dettagli(IDVendita, IDArticolo, Qta)values (1, 5, 4);
insert into dettagli(IDVendita, IDArticolo, Qta)values (1, 7, 2);
Stampare lo scontrino
mysql> SELECT Cliente, Descrizione, Prezzo, Qta
-> FROM (Articoli
-> INNER JOIN dettagli
-> ON Articoli.IDarticolo=dettagli.IDArticolo)
-> INNER JOIN Scontrino
-> ON dettagli.IDVendita=scontrino.IDVendita;
+-------------+---------------------+--------+------+ | Cliente | Descrizione | Prezzo | Qta | +-------------+---------------------+--------+------+ | Rossi Mario | Passata di Pomodoro | 2.00 | 2 | | Rossi Mario | dado vegetale | 0.90 | 4 | | Rossi Mario | nutella 200g | 2.20 | 6 | +-------------+---------------------+--------+------+ 3 rows in set (0.00 sec)
Calcolare l'importo totale dello scontrino:
mysql> SELECT sum(Prezzo*Qta) as Totale
-> FROM (Articoli inner join dettagli
-> ON Articoli.IDarticolo=dettagli.IDArticolo)
-> INNER JOIN Scontrino
-> ON dettagli.IDVendita=scontrino.IDVendita;
+--------+ | Totale | +--------+ | 20.80 | +--------+ 1 row in set (0.00 sec)
L'emissione di una fattura, o anche di uno scontrino su moduli di dimensione prestabilita, non quindi su moduli continui, potrebbe richiedere che si controlli il numero di articoli stampati su ciascun modulo.
Al riguardo il comando SELECT prevede il campo opzionale LIMIT per specificare i gruppi di elementi
da stampare in una pagina:
La sintassi è:
SELECT * FROM TABELLA LIMIT inizio, quantità
Si provi l'esempio seguente:
mysql> select * from Articoli limit 3, 5;
+---------------+------------+-----------+--------+---------+ | Descrizione | IDArticolo | QtaScorta | Prezzo | reparto | +---------------+------------+-----------+--------+---------+ | Shampoo | 4 | 95 | 2.25 | 1 | | dado vegetale | 5 | 250 | 0.90 | 2 | | olio di oliva | 6 | 20 | 4.50 | 2 | | nutella 200g | 7 | 80 | 2.20 | 3 | | miele acacia | 8 | 60 | 4.80 | 3 | +---------------+------------+-----------+--------+---------+ 5 rows in set (0.03 sec)
Vengono stampate 5 righe della tabella Articoli, a iniziare dalla riga numero 3.
Una delle possibili applicazioni dei Trigger è quella di mantenere l'integrità referenziale dei dati. Quando un utente effettua un acquisto si devono eseguire alcune operazioni. La prima delle quali potrebbe essere: inserire il costo del prodotto acquistato in una tabella. In seguito a questa operazione si potrebbe innescare l'esecuzione delle altre: decrementare, dal carico di magazzino, la quantità di articoli acquistati, formare il totale parziale dei prodotti acquistati.
I Trigger sono oggetti del data base come lo sono le tabelle. I trigger, però, sono in grado di eseguire istruzioni che modificano i dati nelle tabelle. Nel caso specifico si vuole eseguire il trigger prima di un'istruzione di inserimento di record nella tabella dettagli. Quando si inserisce un record in questa tabella bisogna aggiornare il record collegato nella tabella Articoli.
Prima di scrivere il codice del trigger al prompt di MySql, eseguire la seguente istruzione: Delimiter $$
La presenza di questa istruzione è dovuta al fatto che il codice usa i punti e virgola alla fine di ogni istruzione, quindi si deve impostare un delimitatore differente, per informare MySQL di come interpretare le istruzioni nel blocco di programma. Ricordare di ripristinare il delimitatore punto e virgola al termine del blocco di istruzioni.
Il codice del programma del trigger è il seguente:
mysql> delimiter $$
mysql> CREATE TRIGGER ArtVenduti
-> BEFORE INSERT ON dettagli FOR EACH ROW
-> BEGIN
-> UPDATE Articoli
-> SET QtaScorta=QtaScorta-NEW.Qta
-> WHERE IDArticolo= NEW.IDArticolo;
-> END$$
Query OK, 0 rows affected (0.01 sec)
mysql> delimiter ;
L'istruzione CREATE TRIGGER è l'intestazione del trigger, gli si assegna il nome 'ArtVenduti'. I trigger possono essere richiamati prima di un evento INSERT, UPDATE o DELETE.
Nel caso specifico esso viene richiamato prima che venga inserito un record nella tabella dettagli.
L'istruzione FOR EACH ROW significa che il blocco agisce su ogni riga che soddisfa i criteri impostati nella query.
Le parentesi BEGIN ed END delimitano le istruzioni che il trigger eseguirà quando si verifica l'evento.
Il trigger aggiorna (update) la tabella Articoli, assicurando che il campo QtaScorta contenga il valore corretto del numero di articoli disponibili in magazzino.
Inserire dei dati nella tabella dettagli e osservare il contenuto della tabella Articoli. Usare la query:
mysql> insert into dettagli
-> (IDVendita, IDArticolo, Qta)
-> values
-> (1, 4, 5);
Query OK, 1 row affected (0.25 sec)
Osservare il numero di articoli disponibili per il prodotto venduto:
mysql> select * from Articoli where IDArticolo=4;
+-------------+------------+-----------+--------+---------+ | Descrizione | IDArticolo | QtaScorta | Prezzo | reparto | +-------------+------------+-----------+--------+---------+ | Shampoo | 4 | 95 | 2.25 | 1 | +-------------+------------+-----------+--------+---------+ 1 row in set (0.05 sec)
Problemi:
Individuare una possibile applicazione del trigger agli eventi before UPDATE e before DELETE.
suggerimenti:
Quando si cancella un record dalla tabella dettagli bisogna incrementare
la quantità di articoli disponibili in magazzino.
Quando invece si modifica il numero di articoli venduti in una riga del record dettagli, ad esempio invece di scrivere Qta=3 si è scritto Qta=4, bisogna rimettere in magazzino i 4 articoli erroneamente venduti e sottrarre i 4 effettivamente venduti.
Per fare riferimento ai campi della tabella associata al trigger si possono usare i sinonimi OLD e NEW. Il riferimento OLD.campo si riferisce ad un campo di una riga esistente prima che venga aggiornata o cancellata. Il riferimento NEW.campo si riferisce al campo di una nuova riga che deve essere inserita o a una riga esistente dopo che viene aggiornata.
Per modificare un trigger bisogna prima cancellarlo e poi riscriverlo. L'istruzione per cancellare un trigger è:
DROP TRIGGER nome del trigger;