• Non ci sono risultati.

ISTITUTO TECNICO INDUSTRIALE STATALE "G. Fauser" NOVARA Manuale di Informatica con i seguenti argomenti: SQL MySQL HTML PHP

N/A
N/A
Protected

Academic year: 2021

Condividi "ISTITUTO TECNICO INDUSTRIALE STATALE "G. Fauser" NOVARA Manuale di Informatica con i seguenti argomenti: SQL MySQL HTML PHP"

Copied!
20
0
0

Testo completo

(1)

ISTITUTO TECNICO INDUSTRIALE STATALE

"G. Fauser"

NOVARA

Manuale di Informatica con i seguenti argomenti:

SQL MySQL

HTML

PHP

(2)

Indice

STRUCTURED QUERY LANGUAGE ...

Data Definition Language (DDL) ...

Operazioni sulle TABELLE ...

DDL ...

Definizione della Tabella...

Inserimento di un nuovo Attributo ...

Cancellazione di un Attributo ...

Sostituzione del campo chiave con altro campo ...

Modificare il tipo di un campo ...

Creazione di un Indice...

Cancellazione di una Tabella ...

Cancellazione di un Indice ...

Rinominare una tabella...

Rinominare un campo ...

Manipolazione dei dati (DML) ...

Operazione sui DATI ...

DML ...

Inserimento di un nuovo Record ...

Cancellazione di un Record ...

Modifica di un Campo ...

Query Language (QL) ...

Interrogazione dei dati: comando SELECT ...

Struttura generale ...

Predicato ALL ...

Predicato DISTINCT ...

Clausola AS ...

Select con Parametri ...

Operazioni Relazionali ...

Selezione (opera una selezione delle righe) ...

Proiezione (opera una selezione delle colonne) ...

Congiunzione ...

Esempi di Selezione, Congiunzione e Proiezione insieme ...

Clausola INTO ...

Comando INSERT INTO ...

Funzioni di AGGREGAZIONE ...

Funzione COUNT ...

Funzione SUM ...

Funzione AVG ...

Funzione MIN e MAX ...

Ordinamenti ...

Clausola ORDER BY ...

Raggruppamenti ...

Clausola Group By ...

Clausola HAVING ...

Condizioni di ricerca ...

Operatore BETWEEN ...

Operatore IN ...

Operatore LIKE ...

Operatore IS NULL ...

(3)

Comandi per la sicurezza (DCL) ...

Comandi GRANT e REVOKE ...

Le VISTE ...

Comando CREATE VIEW e DROP VIEW ...

Interrogazioni nidificate ...

Alcuni esempi ...

Predicato ANY ...

Predicato ALL ...

Predicato IN ...

Predicato EXISTS ...

Età di una persona ...

Predicato JOIN (2 tab) ...

Predicato JOIN (3 o + tab) ...

HTML ...

Elementi di base di un documento HTML ...

Tabella ...

FORM ...

Elementi di un Form ...

MySQL ...

Numerici ...

Data e ora ...

Stringhe ...

Le principali funzioni incluse in MySQL ...

Funzioni matematiche ...

Funzioni per le stringhe di caratteri ...

Funzioni data e ora ...

Altre Funzioni...

PHP ...

Funzioni per la gestione degli array ...

Funzioni MySQL ...

Riempimento tabella HTML ...

Gestione delle sessioni ...

Altre funzioni ...

Istruzioni PHP ...

(4)

STRUCTURED QUERY LANGUAGE

Data Definition Language Operazioni sulle TABELLE D

Definizione della Tabella

CREATE TABLE nomeTabella (NomeCampo1 Tipo,

NomeCampo2, Tipo [not null]*,

……….

Primary Key(NomeCampo1),

Foreign Key (NomeCampox) references NomeTabellax(NomeCampoTabellax) [ON DELETE azione**]

[ON UPDATE azione**]

* in tutte le righe della tabella questa colonna deve essere riempita ) ;

** azione può essere

-CASCADE =in caso di cancellazione o modifica della chiave nella tabella padre vengono aggiornati o cancellati anche tutti i record collegati nella tabella figlia;

-SET NULL= in caso di modifica della chiave o cancellazione del record nella tabella padre, nei record collegati della tabella figlia la chiave esterna viene impostata a NULL;

-RESTRICT viene impedita la modifica della chiave o la cancellazione di un record che ha record collegati nella tabella figlia, E’ il valore di default. (idem NO ACTION)

D L

Inserimento di un nuovo Attributo ALTER TABLE nomeTabella

ADD nomeAttributo Tipo [AFTER nomeCampo];

Cancellazione di un Attributo ALTER TABLE nomeTabella DROP nomeAttributo;

Sostituzione del campo chiave con altro campo

ALTER TABLE nomeTabella Drop Primary Key, ADD Primary Key(nuovoCampoChiave);

Modificare il tipo di un campo ALTER TABLE nomeTabella CHANGE nomeCampo nuovoTipo;

Creazione di un Indice

CREATE [UNIQUE]* INDEX nomeIndice ON nomeTabella (Attributi1, Attrib2..);

* se non si vogliono valori duplicati

Cancellazione di una Tabella DROP TABLE nomeTabella;

Cancellazione di un Indice

DROP INDEX nomeIndice ON nomeTabella;

Rinominare una tabella

ALTER TABLE nomeVecchio RENAME nomeNuovo;

Rinominare un campo

ALTER TABLE nomeTabella

CHANGE nomeCampoVecchio

nomeCampoNuovo Tipo;

(5)

Manipolazione dei dati (DML) Operazione sui DATI D Inserimento di una tupla

INSERT INTO nomeTabella (Campo1, Campo2, …….. Campon)

VALUES (‘Dato1’, ‘Dato2’, ………,Daton);

M L

Cancellazione di una o piu tuple DELETE FROM nomeTabella WHERE [ condizioni ];

Modifica di un Campo UPDATE nomeTabella

SET campo=’dato’,[campo1=dato1]

WHERE [ condizioni ];

Query Language

Interrogazione dei dati: comando SELECT

Struttura generale

SELECT [*] Campo1, Campo2, ….. Campon FROM Tabella1, Tabella2, ……. Tabellan WHERE Condizione; **

* Mettendo l’* si intendono tutti gli attributi

** Si possono combinare più condizioni con gli operatori OR, AND e NOT

Predicato ALL

Indica la richiesta di tutte le righe che soddisfano le condizioni del comando. Essendo di default non è necessario specificarlo

Predicato DISTINCT

Le righe che risultano doppie sono ridotte a una.

SELECT DISTINCT nomeCampo FROM nomeTabella;

Clausola AS

I nome dei campi della tabella risultante dall’interrogazione tramite Select sono uguali ai campi che sono stati selezionati. Se si vogliono cambiare si usa AS.

SELECT campoTabPartenza AS campoTabArrivo FROM TabPartenza;

Supporta anche il calcolo di espressioni

Operazioni Relazionali

Selezione (opera una selezione delle righe) Si usa la clausola WHERE del comando Select

Proiezione (opera una selezione delle colonne) Si scelgono solo alcuni dei campi della tabella

(6)

Congiunzione

La congiunzione tra più tabelle si ottiene

elencando le tabelle dopo il FROM, separate dalla virgola e nella clausola WHERE l’uguaglianza degli attributi in comune.

Si puo’ utilizzare la notazione punto per chiarezza:

NomeTabella.NomeCampo

Self-join: congiunzione della tabella con se stessa (ad es. si vuole aggiungere un nuovo campo che contiene valori di altri campi). Per risolverlo si usa l’alias per il nome della tabella, si definiscono cioè 2 nomi diversi (con AS) per la stessa tabella

Elenco di tutti i dipendenti con descrizione e indirizzo della filiale ove lavorano

SELECT *

FROM Personale, Dipendenza WHERE Filiale = CodFiliale

* con il segno = si chiama equi-join ---

Elenco per ciascun dipendente, del proprio dirigente

SELECT Tab1.Cognome, Tab1.Nome, Tab2.Cognome FROM Personale AS Tab1, Personale As Tab2 WHERE Tab1.Dirigente = Tab2.Matricola;

Clausola INTO

Consente di memorizzare il risultato dell’operazione in una tabella SELECT * INTO NuovaTabella

FROM VecchiaTabella WHERE Condizione

Comando INSERT INTO

Consente di aggiungere nuovi record provenienti da un’altra tabella INSERT INTO VecchiaTabella

SELECT *

FROM NuovaTabella;

(7)

Funzioni di AGGREGAZIONE

Funzione COUNT

Conta il nr. di righe presenti in una tabella. Essa vuole un parametro che può essere il nome di un campo oppure l’*.

Con il nome del campo le celle contenenti NULL non vengono contate. Invece se si usa * vengono contate anche le celle contenenti NULL.

Consente di ottenere il nr. delle righe che soddisfano la condizione.

COUNT(DISTINCT x)

Consente di ottenere il nr. dei valori diversi tra loro nella colonna x che soddisfano la condizione scritta dopo WHERE.

La clausola Distinct non può essere usata nel formato Count(*).

Il risultato del conteggio può essere descritto con un’opportuna intestazione aggiungendo la clausola AS.

Funzione SUM

Somma degli stipendi dei dipendenti del livello 5 SELECT SUM(Stipendi)

FROM Personale WHERE Livello = 5;

---

Se il totale delle fatture viene calcolato come Quantità * Prezzo allora il Totale può essere così calcolato:

SELECT SUM(PrezzUnit * Quant) AS Totale FROM Fatture;

Restituisce la somma di tutti i valori contenuti in una colonna specificata come argomento della funzione.

Se nel comando SELECT è presente la condizione WHERE, la funzione somma solo le righe che soddisfano la condizione. NULL viene considerato 0 SELECT SUM(DISTINCT Stipendi)

Consente di sommare solo gli stipendi diversi tra loro.

L’argomento può essere anche un’espressione numerica.

Funzione AVG

Restituisce la media dei valori (numerici) contenuti in una colonna. L’argomento può essere anche un’espressione numerica. Essa non include nel calcolo i valori di tipo NULL

Si può aggiungere l’opzione Distinct.

Funzione MIN e MAX

Calcolo dello stipendio minimo e massimo dei dipendenti SELECT MIN(StipBase), MAX(StipBase)

FROM Personale;

--- Il primo e l’ultimo cognome dei dipendenti

SELECT MIN(Cognome), MAX(Cognome) FROM Personale;

Restituisce il valore minimo/massimo tra quelli di una determinata colonna specificata come argomento.

Può essere utilizzata anche per campi di tipo carattere.

Si può utilizzare la clausola Where. L’argomento può essere un’espressione numerica ignorano i campi con valore NULL.

Ordinamenti

Clausola ORDER BY

Consente di ottenere i risultati dell’interrogazione ordinati secondo i valori di 1 o + colonne tra quelle elencate nella Select. L’ordinamento è crescente (ASC) per default quindi è necessario specificarlo solo per il decrescente (DESC).

SELECT Campo1, Campo2,….. Campon FROM Personale

ORDER BY Campo1, Campon;

Per gli ordinamenti complessi occorre specificare Desc per i campi ordinati in senso decrescente.

Generalmente la clausola Order By è l’ultimo elemento di 1 comando SQL.

Raggruppamenti

Clausola Group By Elenco delle funzioni dei dipendenti con la somma degli stipendi e il Con le f. di aggregazione (Sum, Count) è possibile numero dei dipendenti appartenenti alle diverse funzioni.

estendere la struttura del comando Select con SELECT Funzione, SUM(StipBase), COUNT(*) l’aggiunta di Group By. Si crea quindi una riga FROM Personale

per ogni raggruppamento. GROUP BY Funzione;

Se la Select non contiene 1 f. di aggregazione i

(8)

valori di raggruppamento non vengono prodotti in

output. Elenco dei livelli esistenti tra i dipendenti che svolgono la f. di Impiegato Tutti gli attributi che compaiono accanto con il nr. di dipendenti per ciascun livello.

alla Select devono essere inclusi nel Group By SELECT Livello, COUNT(Livello) AS Conteggio oppure devono essere argomenti di 1 f. di FROM Personale

aggregazione. WHERE Funzione = ‘Impiegato’

GROUP BY Livello;

Clausola HAVING

La Select con raggruppamento può essere ampliata con Having: essa sottopone al controllo di 1 o + condizioni i gruppi creati con Group By.

La condizione dopo Having normalmente controlla il valore restituito dalle f. di aggregazione (Count,Sum, Avg, ecc.).

In genere, quindi, Having viene usata insieme a Group By: dopo che Group By haformato i raggruppamenti di righe, Having serve a visualizzare le righe che soddisfano alle condizioni scritte accanto a Having. Se la Select contiene la clausola Where, i valori vengono raggruppati dopo aver operato la selezione sulle righe che rispettano

le condizioni scritte accanto a Where. Quindi Where agisce sulle righe della tabella mentre Having sulle righe contenenti i risultati delle f. di aggregazione.

Condizioni di ricerca

Sono utilizzate insieme alle clausole Where e Having per determinare i criteri di selezione rispettivamente delle righe e dei raggruppamenti. Si utilizzano gli operatori relazionali (>, =, <, <=, ecc.) e booleani (And, Not, Or) e altre parole del linguaggio SQL che rendono la ricerca più raffinata; vedere di seguito.

Operatore BETWEEN val1 AND val2

Controlla se un valore è compreso all’interno di 1 intervallo di valori, estremi inclusi. NOT Between valuta la condizione opposta.

Operatore IN

Controlla se un valore appartiene ad un insieme specificato di valori. Anche IN può essere preceduto da NOT.

SELECT …….

FROM Tabella

WHERE Campox IN (elenco);

Operatore LIKE

Confronta il valore di un attributo di tipo carattere con un modello di stringa che può contenere i caratteri jolly (_ : un carattere qualsiasi; %: una stringa qualsiasi).

Like ‘xyz%’: la stringa inizia per xyz Like ‘%xyz’: la stringa finisce per xyz Like ‘%xyz%’: la stringa contiene xyz Like ‘_xyz’: 4 caratteri di cui xyz di fine.

Like senza caratteri jolly equivale a =. Anche Like

(9)

Comandi per la sicurezza (DCL)

Comandi GRANT e REVOKE Per concedere il diritto di modifica sulla tabella dei dipendenti agli utenti denominati User1 e User2

GRANT UPDATE ON Personale TO User1, User2;

Revoca dei permessi con annullamento dei diritto di accesso del comando precedente

REVOKE UPDATE ON Personale TO User1, User2;

Concessione del diritto di modifica del livello e dello stipendio dei dipendenti all’utente User3.

GRANT UPDATE (Livello, StipBase) ON Personale

TO User3;

Concede i permessi, specificando il tipo di accesso, le tabelle sulle quali è consentito l’accesso e

l’elenco degli utenti ai quali è permesso di

accedere. I permessi che possono essere concessi (revocati) agli utenti sono indicati con le parole chiave che vanno specificate dopo Grant o Revoke - ALTER (aggiungere/eliminare colonne o

modificare i tipi di dati)

- DELETE (eliminare righe dalle tabelle) - INDEX (creare indici)

- INSERT (inserire nuove righe nelle tabelle) - SELECT (per trovare dati nelle tabelle)

- UPDATE (cambiare i dati contenuti nelle tab.) - ALL (tutti i permessi precedenti).

I permessi con le opzioni Select e Update, nei comandi

Grant e Revoke, diventano + restrittivi specificando tra

parentesi e separati da virgola, i nomi delle colonne che

l’utente può vedere o modificare.

(10)

Le VISTE

Il linguaggio SQL consente di decidere le modalità con le quali gli utenti possono vedere le tabelle del database, creando una finestra, detta VIEW (vista), su alcuni o su tutti i dati contenuti in 1 o + tabelle.

Comando CREATE VIEW e DROP VIEW Creazione di una vista di nome Impieg contenente i dati degli La limitazione della vista ad una visione parziale Impiegati.

della tabella consente di eliminare il rischio di CREATE VIEW Impieg modifiche indesiderate su dati che non competono AS SELECT *

ad un determinato utente. La vista viene considerata FROM Personale

quindi come se fosse una tabella e quindi le WHERE Funzione = ‘Impiegato’;

modifiche fatte sulla vista si riflettono sulla tabella --- originale (finestre dinamiche). Le viste che Eliminazione della vista precedente.

contengono risultati di funzioni di aggregazioni non DROP VIEW Impieg;

sono aggiornabili/modificabili. ---

Il comando Drop View consente l’eliminazione della Concessione all’utente User3 al diritto di accedere alla vista Impieg

vista. GRANT SELECT

Il creatore della vista, usando il comando Grant, ON Impieg fornisce all’utente il diritto di accesso ai dati TO User3;

attraverso l’utilizzo della vista.

Quindi i sottoschemi e le autorizzazioni per utenti diversi su un database relazione possono essere definiti con l’SQL usando in modo combinato i comandi Create View e Grant.

Interrogazioni nidificate

All’interno di un comando Select è possibile inserire un altro comando Select (interrogazione all’interno di un’altra interrogazione: subquery). Da qui Structured della sigla SQL perché il linguaggio consente di costruire interrogazioni complesse e ben strutturate .

Alcuni esempi Elenco con cognome e nome dei dipendenti che hanno lo stipendio

Il comando Select nidificato restituisce il valore inferiore allo stipendio medio di tutti i dipendenti calcolato del valor medio degli stipendi; questo nr. SELECT Cognome, Nome

viene usato poi nell’interrogazione principale per il FROM Personale confronto con i valori dell’attributo StipBase nel WHERE StipBase <

criterio di selezione delle righe della tabella, scritto (SELECT AVG(StipBase)

dopo Where. FROM Personale);

La condizione scritta dopo Where confronta il valore ---

di un attributo con il risultato di un altro comando Elenco dei dipendenti, elencati in ordine alfabetico cognome, nome e Select. Una subquery può restituire un valore descrizione della filiale dove lavorano, per i quali lo stipendio risulta singolo, nessun valore oppure un insieme di uguale al valore massimo tra tutti gli stipendi dei dipendenti con la valori, ma deve comunque avere una singola funzione di impiegato.

colonna o espressione accanto alla sua Select. SELECT Cognome, Nome, Descrizione

L’interrogazione si ottiene con la congiunzione tra le 2 tabelle FROM Personale, Dipendenza,

Personale e Dipendenza, realizzata attraverso l’attributo comune WHERE Filiale = CodFil AND

del codice filiale; la condizione di selezione sulle righe risultanti StipBase = (SELECT MAX(StipBase)

confronta lo stipendio di ogni dipendente con il valore ottenuto

FROM Personale

da una sottointerrogazione che restituisce 1 nr., ottenuto

calcolando con la f. Max il valore massimo tra tutti i valori di WHERE Funzione = ‘Impiegato’)

StipBase. ORDER BY Cognome, Nome;

Predicato ANY

Indica che la subquery può restituire zero, oppure 1, oppure 1 insieme di valori, e che la condizione di ricerca è vera se il confronto è vero per almeno 1 dei valori restituiti. La condizione di ricerca è falsa se la subquery restituisce 1 insieme vuoto oppure se il confronto è falso per ciascuno dei valori restituiti dalla subquery.

Elenco dei dipendenti che non sono impiegati e che hanno lo stipendio superiore a quello di uno qualsiasi tra gli impiegati.

SELECT Cognome, Nome, Funzione FROM Personale

WHERE Funzione <> ‘Impiegato’ AND StipBase > ANY (SELECT StipBase

FROM Personale

WHERE Funzione = ‘Impiegato’);

(11)

Predicato ALL Elenco di tutti di dipendenti che non sono impiegati e che hanno lo Indica che la subquery può restituire zero, oppure 1, stipendio superiore a quello di tutti gli impiegati.

oppure 1 insieme di valori, e che la condizione di

ricerca è vera se il confronto è vero per ciascuno dei valori Basta sostituire ALL a ANY

restituiti. La condizione di ricerca è falsa se il SELECT Cognome, Nome, Funzione confronto è falso per almeno 1 tra i valori restituiti FROM Personale

dalla subquery. WHERE Funzione <> ‘Impiegato’ AND

Ovviamente l’interrogazione con ALL restituisce 1 nr StipBase > ALL (SELECT StipBase

inferiore di righe rispetto a ANY. FROM Personale

Le clausole Any e All possono essere tralasciate nelle espressioni WHERE Funzione = ‘Impiegato’);

di confronto se si è in grado di stabilire che la subquery restituirà sicuramente un solo valore. In questo caso la condizione di ricerca è vera se è vero il confronto tra il valore dell’attributo e il valore restituito dalla subquery.

Predicato IN Elenco con cognome e nome dei dipendenti che lavorano nelle filiali che

Serve a controllare se il valore di un attributo è hanno più di 10 dipendenti compreso tra quelli restituiti dalla subquery. SELECT Cognome, Nome È possibile utilizzare NOT IN per estrarre solo le FROM Personale

righe della tabella principale per le quali nessuna riga WHERE Filiale IN (SELECT Filiale della tabella ottenuta con la subquery contiene un FROM Personale

valore =. GROUP BY Filiale

HAVING COUNT(*) >10);

Le seguenti condizioni di ricerca sono equivalenti:

WHERE Attributo IN (SELECT ……..) WHERE Attributo = ANY (SELECT ……..)

WHERE Attributo NOT IN (SELECT ……..) WHERE Attributo <> ALL (SELECT……..)

Predicato EXISTS Elenco dei dipendenti con cognome e nome solo se esistono dipendenti

Controlla se vengono restituite righe dall’esecuzione di sesto livello

della subquery: la condizione di ricerca è vera se la SELECT Cognome, Nome Select nidificata produce 1 o + righe come risultato, è FROM Personale

falsa se la subquery restituisce un insieme vuoto. WHERE EXISTS (SELECT *

Tale predicato è il solo che non confronta un valore con 1 o + FROM Personale

altri valori. Le colonne utilizzate nella subquery di una clausola WHERE Livello = 6);

Exists sono irrilevanti: quindi per brevità si utilizza Select * nella subquery. Exists può essere negato: Not Exists.

Età di una persona

Mostra l’età (in anni) di una persona dalla data SELECT nome, datanas, CURDATE(), corrente. CURDATE fornisce “aaaa-mm-dd” e ( YEAR(CURDATE())-YEAR(datanas) )

RIGHT(stringa, n) estrae n caratteri partendo dalla - (RIGHT(CURDATE(),5) < RIGHT(datanas,5)) AS eta

parte destra della stringa. FROM clienti;

(12)

HTML Elementi di base di un <html>

documento HTML: <head>

<title>Titolo della pagina</title>

</head>

<body>

<!-- qui si crea la pagina vera e propria -->

</body>

</html>

Tabella <TABLE width="50%" border="1">

PARAMETRO WIDTH <TR width="25%">

definisce la larghezza dell'oggetto <th>Colonna1</th>

in percentuale rispetto alla <th>Colonna2</th>

risoluzione dello schermo. <th>Colonna3</th>

<th>Colonna4</th>

TAG TH </TR>

indica l'intestazione delle colonne <TR >

(scritta COLONNA1 in grassetto) <td width="25%">dato01</td>

<td>dato02</td>

PARAMETRO BORDER <td>dato03</td>

definisce la dimensione del bordo <td>dato04</td>

della tabella. </TR>

</TABLE>

Link <a href="MenuPrincipale.html">Ritorna al menù principale </a>

FORM: <form name="nomeForm" action="fileScript.php" method="POST ">

(contenitore di oggetti quali: Text <!-- qui si inseriscono gli elementi -->

Box, Combo Box, Pulsanti, ... ) </form>

Elementi di un Form:

Text Box <INPUT type=“TEXT" name="Utente">

<INPUT type=“PASSWORD" name="PwdUtente">

Check Box <INPUT type=”CHECKBOX” name=”N”>Nuoto

<INPUT type=”CHECKBOX” name=”T”>Tennis

Radio Button <INPUT type=”RADIO” name="Nazione" value=”Italia”> ITALIA

<INPUT type=”RADIO” name ="Nazione" value=”Francia”> FRANCIA Combo Box (Selezione) <SELECT name="NomeCombo">

<OPTION value="Citta1" SELECTED>Roma</OPTION>

<OPTION value="Citta2">Rimini</OPTION>

<OPTION value="Citta3">Ravenna</OPTION>

</SELECT>

Pulsanti <INPUT type="SUBMIT" value="Invia">

<INPUT type="RESET" value="Annulla">

<INPUT type="BUTTON" name="B1" value="Calcola"

onClick="nomeProcedura">

(13)

Tipi di dati MySql

Numerici

B Tipo valore minimo Valore massimo

1 BIT [(M)]

1 TINYINT [(M)] [UNSIGNED] [ZEROFILL] -128 (0) +128 (255)

2 SMALLINT [(M)] [UNSIGNED] [ZEROFILL] -32768 (0) +32767 (65535)

3 MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL] -8988608 (0) +8988607 (16777215)

4 INT [(M)] [UNSIGNED] [ZEROFILL] -2147483648 (0) +2147483647

8 BIGINT [(M)] [UNSIGNED] [ZEROFILL] -2

63

(0) +2

63

-1 (+2

64

-1)

4 FLOAT [(M,D)] [UNSIGNED] [ZEROFILL]

8 DOUBLE [(M,D)] [UNSIGNED] [ZEROFILL]

DECIMAL [(M[,D])] [UNSIGNED] [ZEROFILL]

Bit (si può usare anche Bool) è sinonimo di TINYINT(1): 0=FALSE, 1=TRUE.

L’opzione UNSIGNED specifica che il numero è senza segno (questo comporta la possibilità di memorizzare solo numeri positivi ma si recupera il bit del segno e quindi si possono memorizzare numeri più grandi), mentre l’opzione ZEROFILL indica al server di memorizzare i numeri con degli zeri davanti nel caso in cui la lunghezza sia inferiore a quella massima prevista.

I dati di tipo TINYINT, SMALLINT, MEDIUMINT, INT e BIGINT rappresentano numeri interi composti rispettivamente da 1, 2, 3, 4 e 8 bytes. I tipi FLOAT e DOUBLE rappresentano i numeri in virgola mobile. Il tipo DECIMAL corrisponde ai numeri rappresentati nel formato virgola fissa (4 bit ogni cifra), con M cifre totali di cui D decimali.

Esiste anche il tipo BOOL che corrisponde a TINYINT (0=falso, un valore diverso da 0=vero).

Data e ora

3 DATE

8 DATETIME da '1000-01-01 00:00:00' a '9999-12-31 23:59:59'

4 TIMESTAMP[(M)]

3 TIME da ’-838:59:59’ a ’+838:59:59’

1 YEAR [(2|4)] da 70 a 69 o da 1970 a 2155

Stringhe

detta L la lunghezza della stringa Byte occupati

[NATIONAL] CHAR(M) [BINARY | ASCII | UNICODE] (M byte se ACII)

[NATIONAL] VARCHAR(M) [BINARY] 0<=M<=65535 (L+1 byte se L<255 o L+2)

BINARY(M) 0<=M<=255 (L+1 byte)

VARBINARY(M) 0<=M<=65535 (L+1 byte se L<255 o l*2)

TINYBLOB max 255 caratteri L+1

TINYTEXT max 255 caratteri L+1

BLOB [(M)] max 65535 char l+2

TEXT [(M)] max 65535 char l+2

MEDIUMBLOB max 16777215 char L+3

MEDIUMTEXT max 16777215 char L+3

LONGBLOB max 4GB L+4

LONGTEXT max 4GB Lè4

ENUM ('valore1','valore2',...) 1 o 2 bytes

SET ('valore1','valore2',...) 1,2,3,4 o 8 bytes

Il tipo CHAR è una stringa di lunghezza fissa (M) riempita con spazi a destra al momento della memorizzazione. L’opzione NATIONAL indica che la stringa deve usare il set di caratteri di default.

L’attributo BINARY fa diventare case sensitive. Il tipo VARCHAR è una stringa di lunghezza

variabile. I tipi BINARY e VARBINARY corrispondono a CHAR e VARCHAR, ma memorizzano

stringhe di byte invece che di caratteri. I tipi BLOB e TEXT sono utilizzati rispettivamente per valori

binari e di testo. Un tipo ENUM può contenere uno solo dei valori elencati nella definizione (max

65535), oppure NULL (in realtà contiene un numero di 1 o 2 byte). Un tipo SET, può contenere 1 o

più dei max 64 valori possibili.

(14)

Le principali funzioni incluse in MySQL

Le funzioni e, più in generale, le espressioni possono essere utilizzate per la definizione di campi calcolati nelle query (dopo SELECT) oppure nelle clausole where, having e anche group by, order by.

Funzioni matematiche

Con MySQL nei calcoli, oltre ai normali operatori +, - , *, / si possono utilizzare:

 % (resto della divisione intera), MOD (sempre resto della divisione intera), DIV (divisione intera); 

  le operazioni sui bit del linguaggio C: & (AND), | (or), ^ (XOR), ~ (inversione dei bit), << (scorrimento a sinistra dei bit), >> (scorrimento a destra) 

Nome Descrizione Esempi

abs(x) Calcola il valore assoluto di x select abs(2.5), abs(-37)

2,5 37

ceiling(x) Restituisce il più piccolo intero >= x, select ceiling(2.3), ceiling(-1.2)

corrisponde all’arrotondamento per eccesso 3 -1

floor(x) Restituisce il più grande intero <= x select floor(2.3), floor(-1.2)

(arrotondamento per difetto) 2 -2

exp(x) Calcola e

x

(dove e è la base dei logaritmi naturali) select exp(2), exp(-2) 7.3890560989307 LN(x) Calcola il logaritmo naturale di x

log(x) oppure log(B,x) select log(2), log(10,100)

log() se richiamato con un solo parametro corrisponde a LN(x) 0.693147180 2 altrimenti calcola il logaritmo in base B di x

round(x) oppure round(x,D) select round(2.3), round(2.6),round(2.5) round() con un parametro arrotnda il numero x all’intero più vicino 2 3 3

mentre con due parametri restituisce il numero x con solo D select round(2.234,2) round(2.567,2) cifre decimali arrotondandolo l’ultima cifra decimale. 2.23 2.57

pow(x,y) calcola x elevato a y con x e y numeri qualsiasi (anche con la select pow(2,4), pow(81, 0.5)

virgola) 16 9

sqrt(x) calcola la radice quadrata di x select sqrt(81), sqrt(4)

9 2

Funzioni per le stringhe di caratteri

Con MySQL l’operatore + converte le stringhe in numeri quindi per effettuare la concatenazione di due o più stringhe di caratteri si deve usare la funzione CONCAT().

Nei confronti tra stringhe di caratteri non c’è differenza tra maiuscole e minuscole.

Le stringhe costanti possono essere racchiuse tra due virgolette doppie (es. “Prova”) o tra due apostrofi (codice ASCII 39 es.

‘Prova’) mentre la virgoletta singola ` (codice ASCII 96) viene utilizzata per delimitare i nomi dei campi e delle tabelle.

Nome Descrizione Esempi

concat(stringa1, stringa2 [, …]) select concat(‘Anna’,’Maria’);

concat() crea una nuova stringa unendo tutte le stringhe passate come AnnaMaria parametri.

length(stringa) select length(‘Informatica’);

length() restituisce la lunghezza in byte della stringa fornita come 11 parametro

left() left(stringa1,n) select left(“Informatica”,4);

restituisce n caratteri della stringa stringa1 a partire da sinistra Info

right() right(stringa1,n) select right(“Informatica”,4);

restituisce n caratteri della stringa stringa1 a partire da destra tica

intrstr(stringa1,stringa2) select instr(‘corso di informatica’,’Info’);

instr() cerca stringa2 all’interno di stringa1, se la trova restituisce la 10

posizione in cui è stata trovata altrimenti zero. select instr(‘corso di informatica’,’Infa’);

0 locate() locate(stringa2,stringa1)

come instr() ma gli argomenti sono invertiti

lcase() lcase(stringa1) oppure lower(stringa1) select lcase(“PROva”);

lower() trasforma la stringa in minuscolo prova

ucase() ucase(strina1) oppure upper(stringa1) selecr upper(“PROva”);

upper() trasforma la stringa in maiuscolo PROVA

substr(stringa1,p,n) oppure substr(stringa1,p) select mid(‘Informatica’,3,2);

substr() mid è un sinonimo di substr fo

mid() Estrae n caratteri dalla stringa stringa1 a partire da quello in

posizione p. Se ci sono solo due parametri estrare dalla stringa select mid(“informatica”,5);

(15)

stringa1 tutti i caratteri a partire da quello in posizione p fino alla matica fine.

replace(stringa1, sub1, sub2) select replace(‘la casa di Mario’,’Mario’,’Pia’);

replace() cerca tutte le occorrenze della sottostringa sub1 in stringa1 e la la casa di Pia

rimpiazza con sub2, in questo caso la ricerca è case sensitive. select replace(“lascia A”,”a”,”o”);

loscio A

lpad(stringa1, lun, str) select lpad(‘345’,6,’0’),

lpad() restituisce la stringa1 con esattamente lun caratteri tagliandola se lpad(‘CD’,7,’axy’);

è troppo lunga o aggiungendo la stringa str a sinistra tante volte 000345 axyaxCD se è troppo corta

rpad() come lpad ma la stringa string1 viene allungata a destra select lpad(‘45’,6,’0’),lpad(‘CD’,7,’axy’);

(aggiungendo la stringa str) se è troppo corta 450000 CDaxyax

repeat() repeat(str, cont) select repeat(‘MySQL’,3);

ripete la stringa str esattamente count volte MySQLMySQLMySQL

trim(stringa1) select trim( ‘ ciao ‘);

elimina gli spazi iniziali e finali da stringa1 ‘ciao’

trim() oppure trim(BOTH ! LEADING | TRAILING car FROM

stringa1) select trim(leading ‘x’ from ‘xxxciaoxx’);

elimina i caratteri car all’inizio (LEADING) oppure alla fine ‘ciaoxx’

(TRAILING) o entrambi (BOTH) nella stringa stringa1

Funzioni data e ora

Una data può essere inserita utilizzando una stringa nel formato anno-mese-giorno, per esempio ‘2011-04-10’ oppure

‘1970/3/21’, si può utilizzare il separatore che si preferisce e si può inserire anche l’anno con due cifre sapendo che

 da 70 a 99 verrà trasformato in 1970 fino a 1999 es. ‘70/3/4’ 1970-03-04

 da 00 a 69 verrà trasformato in 2000 fino a 2069 es. ’21-4-15’ 2021-04-15 Le date valide vanno da ‘1000-01-01’ fino a ‘9999-12-31’

Un’ora viene inserita invece nel formato HH:MM:SS (ore minuti secondi) anche qui si può utilizzare un separatore a piacere.

Si può operare con le date e le ore anche con espressioni aritmetiche del tipo:

‘2011-04-06’ + INTERVAL 50 day – INTERVAL 6 week

in alternativa all’uso delle funzioni date_add() e date_sub() con gli stessi effetti.

Nome Descrizione Esempi

curdate() curdate() da come risultato la data corrente presa select curdate();

dall’orologio del sistema 2011-04-07

curtime() curtime() da come risultato l’ora corrente presa select curtime();

dall’orologio del sistema 17:14:55

now() now() da come risultato la data e l’ora corrente presa select now();

dall’orologio del sistema 2011-04-07 17:16:32

DATE_ADD(date,INTERVAL expr unit), select date_add(‘2011-4-2’, INTERVAL 2

DATE_SUB(date,INTERVAL expr unit) month);

Date_ADD aggiunge un intervallo di tempo ad una date 2011-06-02

mentre date_sub serve per sottrarre un certo intervallo select date_add(‘2011-4-2’, INTERVAL date_add() di tempo da una data. Il risultato è sempre una nuova 100 day);

date_sub() data. 2011-07-11

L’intervallo può essere espresso in giorni, settimane, select date_sub(‘2011-4-2’ INTERVAL 3 mesi, anni, e anche ore, minuti, secondi scrivendo al day);

posto di expr_unit: DAY, WEEK, MONTH, YEAR, 2001-03-30 HOUR, MINUTE, SECOND

datedif(data1,data2) select datediff('2011/04/05',

datediff() fa la differenza tra due date, data1-data2, il risultato è '2011/03/08');

espresso in giorni 28

day() day(data1) month(data1) year(data1) select year(now());

month() servono per estrarre rispettivamente il giorno, il mese e 2011 year() l’anno da una data o da una dataora

hour() hour(dataora1) minute(dataora1) second(dataora1) select second(now());

minute() servono per estrare ore minuti e secondi da una dataora 15

(16)

second() (o solo ora)

dayOfWeek(data1) oppure weekDay(data1) select dayofweek('2011-04-10');

restituisce il giorno della settimana 1

dayOfWeek DayOfWeek() restituisce 1=Domenica, 2=lunedì .. select weekDay('2011-04-10');

WeekDay 7=sabato 6

WeekDay restituisce 0=lunedì, 1= martedì, … 6=domenica

Altre Funzioni

Nome Descrizione Esempi

if(condizione, espr1,espr2) se la condizione è vera da come select if(10>7,1,0) risultato il risultato dell’espressione espr1, altrimenti il risultato 1

if() dell’espressione espr2 select count(if (sesso=’F’,1,NULL))

conta il numero delle femmine (anche 0)

cast(espr AS tipo) oppure convert(espr,tipo)

cast() Converte il risultato dell’espressione espr nel tipo specificato che può essere: CHAR, DATE, DATETIME, TIME, convert() DECIMAL, SIGNED, UNSIGNED, BINARY (stringa con

l’attributo binary)

password(stringa) select password(‘prova’);

Calcola con un algoritmo segreto uno stringa di 41 cifre

esadecimale dipendenti dalla stringa fornita come parametro. '*5A5DBAE1C258F3E8D037F02A6 password() Non esiste l’algoritmo inverso, due stringhe diverse B16BE6570821C5B'

potrebbero dare lo stesso risultato ma la probabilità e molto bassa. E’ il sistema utilizzato da MySQL per crittografare le password degli utenti.

sha(str) oppure sha1(str) select sha(‘prova’);

produce una stringa di 40 cifre esadecimali (160 bit) in output ‘ 46c3d962f31452b970069e96ba6d calcolate con l’algoritmo SHA1 a partire dalla stringa str di 741b4fd276a5'

sha() lunghezza arbitraria. Può esser usato per crittografare una sha1() stringa, per esempio una password e il risultato è più sicuro

che con la funzione MD5(), non è disponibile la funzione inversa ma si tratta di un algoritmo standard ben conosciuto.

SHA e SHA1 sono uguali.

md5(str) select MD5(‘prova’);

md5() come sha ma il risultato sono 128 bit (32 cifre esad) '27c749230e8f93b76fa0a4b9dc3cc 450'

encode(str,pass_str) decode(str,pass_str) select encode(‘Prova’,’123’);

encode() serve a crittografare e a decrittografare una stringa di caratteri 'b„ ó?'

(str) utilizzando come chiave di crittografia la stringa pass_str. select decode(‘'b„ ó?', '123’) decode() Il risultato è una stringa binaria della stessa lunghezza della ‘Prova’

stringa da crittografare.

(17)

PHP

Funzioni per la gestione degli array

Un array in php può avere come indice un valore numerico o alfanumerico, in quest’ultimo caso si dice associativo.

In ogni caso possiamo immaginare l’array come una tabella con due colonne: chiave e valore. La chiave è l’indice dell’array, ad ogni chiave corrisponde un valore, ogni riga comprende una coppia chiave-valore.

Il motore PHP mantiene internamente per ogni array un puntatore alla posizione corrente. E’ possibile accedere alla chiave e al valore della posizione corrente con le funzioni key() e current(), si può spostare il puntatore in avanti con next(), indietro con prev(), si può riportare all’inizio dell’array con reset() e alla fine con end()

Nome Descrizione Esempi

key() key(vettore) restituisce la chiave (indice) della Visualizza tutti i campi di un modulo posizione corrente del vettore inviato al server con il metodo post.

current() current(vettore) restituisce il valore della reset($_POST);

posizione corrente del vettore for ($i=0;$i<count($_POST);

$i++)

next() next(vettore) avanti di una posizione sposta il puntatore corrente {echo key($_POST).' = '. current($_POST).' <br> ';

prev(vettore) sposta il puntatore corrente

prev() next($_POST); }

indietro di una posizione

end() end(vettore) sposta il puntatore corrente sull’ultima posizione del vettore

reset() reset(vettore) sposta il puntatore corrente alla prima posizione del vettore

count() count(vettore) fornisce il numero degli elementi del vettore

each(vettore) restituisce un vettore di due list($chiave,$valore)=each(vett);

each() elementi: chiave e valore della posizione corrente e sposta // estrae la chiave e il valore dell’elemento la posizione corrente in avanti // corrente del vettore associativo vett

list(var1, var2, var3,….)=vettore <?php

copia gli elementi del vettore nelle variabili var1, var2, $vett=array('Primo','secondo','terzo');

list() var3 ecc. Se il numero delle variabili è minore degli list($a,$b)=$vett;

elementi del vettore copia solo i primi elementi. // $a=Primo $b=secondo Funziona con i vettori numerici

array(valore1, valore2, valore3, ….) $vett=array('Primo','secondo','terzo');

array() restituisce un vettore con indice numerico contenente //vett diventa un vettore inizializzato con tutti i valori forniti come parametri // i tre elementi ‘Primo’,’secondo’,’terzo’

Funzioni MySQL

Nome Descrizione Esempi

mysql_connect([string_server[,string_nome_utente[, <?php

strig_password[bool nuova_conn]]]]) $conn = mysql_connect("localhost", Apre una connessione ad un server MySql. "utente_mysql", "password_mysql") mysql_connect() Restituisce un identificativo di connessione in caso di or die("Connessione non riuscita: "

successo o FALSE in caso di errore. . mysql_error());

Se si apre due volte la stessa connessione viene print ("Connesso con successo");

restituito lo stesso identificativo a meno che non si mysql_close($conn);

mette TRUE al parametro nuova_conn ?>

mysql_close($conn) mysql_close($conn);

Chiude la connessione al server relativa mysql_close() all’identificativo di connessione specificato.

La connessione viene anche automaticamente chiusa al termine dello script.

mysql_select_db(string nome_database [,$conn]) mysql_select_db("aziende") or Imposta il database attivo fra quelli gestiti dal server die (“Impossibile aprire il database: “.

mysql_select_db() MySql. Restituisce TRUE in caso di successo e FALSE mysql_error());

in caso di fallimento. Se non si specifica la connessione viene utilizzata l’ultima aperta.

mysql_query() mysql_query(string query[, $conn]) $sql= “Select * form aziende where

(18)

Invia una query al database. Se si omette la cod=’RN’”;

connessione viene presa l’ultima aperta.. Se la query è if (!($ris=mysql_query($sql))) { una Select (o una SHOW, EXPLAIN, Describe) echo "Errore nel comando: <br />

fornisce come risultato un identificativo di risorsa in $sql <br />";

caso di successo, per gli altri tipi di query restituisce echo mysql_error();

TRUE in caso di successo, in caso di insuccesso exit();

restituisce sempre FALSE. }

si utilizza dopo aver eseguito una query INSERT $sql=”Insert into ….”;

mysql_insert_id() INTO e restituisce il numero generato mysql_query($sql));

automaticamente per l’eventuale campo $codice=mysql_insert_id();

auto_increment del database

mysql_fetch_array ( resource ris) $ris=mysql_query($sql);

restituisce un array sia numerico che associativo $riga=mysql_fetch_array($ris);

contenete una riga della tabella ris che deve essere il mysql_fetch_array risultato dell’esecuzione di una query (Select).

() Ogni volta che viene eseguito prende la riga successiva nella tabella. Se non ci sono più righe restituisce il valore FALSE. Si può tornare indietro o saltare delle righe utilizzando mysql_data_seek.

mysql_num_rows ( resource ris ) $sql= “Select * form aziende where

restituisce il numero di righe della tabella risultato cod=’RN’”;

mysql_num_rows in seguito all’esecuzione di un comando sql $ris=mysql_query($sql);

() SELECT con mysql_query $num=mysql_num_rows(ris);

echo “Numero di aziende di Rimini

= $num”;

mysql_affected_rows ( [$conn])

Restituisce il numero di righe coinvolte mysql_affected_ro dall’esecuzione di un comando SQL come

DELETE, INSERT, UPDATE. Il parametro ws() facoltativo $conn è l’identificativo di

connessione, se non specificato si considera l’ultima aperta.

mysql_data_seek ( resource ris, int numriga )

Sposta il puntatore interno alla riga di una tabella ottenuta come risultato di una SELECT con mysql_query().La successiva chiamata a

mysql_data_seek mysql_fetch_array() dovrebbe restituire questa riga.

Il numero numriga deve essere compreso tra 0 e mysql_num_rows -1. Restituisce TRUE se lo spostamento riesce e FALSE altrimenti.

addslashes ( string sql )

restituisce la stessa stringa passata come parametro con in più il carattere backslash “\”

addslashes() aggiunto prima dei caratteri che richiedono il quoting nelle stringhe sql ovvero prima dei caratteri ‘, “, \ e NULL. Serve per preparare la query prima di eseguirla.

stripslashes ( string str )

restituisce la stessa stringa passata come stripslashes() parametro ma elimina i caratteri backslash “\”

precedentemente aggiunti con funzioni tipo addslashes.

$nomevariabile Dichiarazione variabili $nomehost = "marco";

(19)

Riempimento tabella HTML Riempimento di <TABLE WIDTH="80%" BORDER="1">

una tabella <TR>

HTML dal <TH WIDTH="25%">Cognome</TH>

risultato di una <TH WIDTH="25%">Nome</TH>

query applicata <TH WIDTH="25%">Residenza</TH>

ad un DB <TH WIDTH="25%">Telefono</TH>

MySQL,

</TR>

utilizzando il

<TR>

ciclo WHILE.

<?php ...

$risultati=mysql_query($sql);

while( ($record = mysql_fetch_array($risultati) ) {

//stampo tabella

echo "<TD>" . $record["Cognome"] . "</TD>";

echo "<TD>" . $record[1] . "</TD>";

echo "<TD>" . $record["Residenza "] . "</TD>";

echo "<TD>" . $record[3] . "</TD>";

} ...

?>

Gestione delle sessioni

Nome Descrizione Esempi

session_start() session_start() session_start();

riprende una sessione esistente o avvia una nuova sessione

session_unset() //chiude la sessione

session_unset() cancella tutte le variabili di sessione. Si può fare anche con: session_unset();

$_SESSION=array(); session_destroy();

session_destroy() vedi sopra

session_destroy distrugge e chiude la sessione. Il prossimo accesso apre una nuova sessione

Altre funzioni

Nome Descrizione Esempi

isset() isset($variabile) if (isset($codice)) $codice++

restituisce vero se la variabile è stata inizializzata else $codice=1;

date ( string formato [, int timestamp] ) echo date("Y-m-d H:i:s");

restituisce una stringa contenente la data (ed eventualmente ora) 2011-06-04 17:23:48 formattata secondo il formato specificato. Se non si fornisce il

secondo parametro che rappresenta la data e l’ora nel formato timestamp di unix, verrà visualizzata la data di sistema.

Il primo parametro è una stringa contenente caratteri speciali che indicano come costruire la stringa contenente la data e/o date() ora. I principali caratteri speciali sono:

d giorno del mese con due cifre m mese dell’anno con due cifre y anno con due cifre

Y anno con 4 cifre

h ore nel formato a 12 ore da “00” a “12”

H ore nel formato a 24 ore da “00” a “23”

i minuti da “00” a “59”

s secondi da “00” a “59”

(20)

w giorno della settimana da “0” domenica a “6” sabato z giorno dell’anno da “0” a “365”

mktime ( int ora, int minuti, int secondi, int mese, int giorno, echo(“Y-m-d”,mktime(0,0,

int anno [, int is_dst] ) 0,6,5,2011))

mktime()

restituisce un numero intero corrispondente al valore timestamp 2011-06-05 di unix per la data e ora specificati come parametri

l’ultimo parametro facoltativo indica se applicare o meno l’ora legale (is_dst=1 per l’ora legale, 0 ora solare e -1 in automatico)

Istruzioni PHP

Nome Descrizione Esempi

include $nomefile vars.php

Serve per includere nel punto dove è inserita l’istruzione il file con <?php

codice php o html avente come nome quello specificato dal $colore = 'verde';

parametro $nomefile che può essere una stringa costante. $frutto = 'mela';

?>

L’unica differenza tra include e require è che nel primo caso se il

include file non c’è lo script prosegue, mentre nel secondo caso viene test.php

require interrotto. <?php $a='Una';

Il codice php nei file da includere deve essere sempre racchiuso tra include 'vars.php';

<?php e ?>. echo "$a $frutto $color

Il file verrà cercato nelle directory indicate nel parametro e";

include_path del file di configurazione php.ini. // Una mela verde

?>

Riferimenti

Documenti correlati

[r]

[r]

La prima fase del concorso prevede una selezione delle migliori iniziative imprenditoriali sulla base di un business plan che descriva dettagliatamente l’idea d’impresa che si intende

Per dimostrare che in alcuni casi la legge del valore estremo EV1 non è adeguata a descrivere le scie degli estremi idrologici, si può far ricorso ad un test molto semplice, nel

Per dimostrare che in alcuni casi la legge del valore estremo EV1 non è adeguata a descrivere le scie degli estremi idrologici, si può far ricorso ad un test molto semplice, nel

Di conseguenza, se il valore max campionato su N dati risulta essere superiore al valore limite al 95% dei massimi su N dati estratti da una Gumbel, tale distribuzione mostra

Elenco dei dipendenti, elencati in ordine alfabetico cognome, nome e descrizione della filiale dove lavorano, per i quali lo stipendio risulta uguale al valore massimo tra tutti

Salvatore Scialpi - www.numerica.altervista.org Pag... Salvatore Scialpi - www.numerica.altervista.org