Introduzione al Linguaggio SQL

 

Flavio Bernardotti (Computer Consulting - Alessandria) SUBLINK: !yachaya!montal!flavio

FIDONET: 2:334/2 - ** PUBLIC DOMAIN SOFTWARE **

 

 

Indice

 

1. Introduzione  1

1.1 Concetti generali 1

2. Il linguaggio SQL 3

2.1. SELECT  4

2.2. WHERE  5

2.3. Operatori matematici di SQL 9

3. Tabelle  13

4. Subquery  14

5. View  15

6. Modifica record  16

7. Creazione Tabelle  18

7.1. Privilegi sulle Tabelle  20

8. Fine  21

 

Indietro

1. Introduzione

 

SQL (pronunciato "sequel") è un linguaggio per la gestione di database molto semplice in quanto legato al metodo di espressione della lingua inglese.

Oltre a questo SQL è abbastanza limitato come numero di vocaboli.

La limitazione del numero delle parole ma allo stesso tempo la strutturazione a linguaggio naturale fa si che le espressioni possibili mediante i suoi vocaboli siano praticamente illimitate.

SQL oltre tutto non si preoccupa dei livelli fisici del database.

In altre parole le gestioni dei file di dati e degli indici diventano completamente trasparenti all'utente.

Come vedremo l'affermazione è solo in parte esatta in quanto SQL può creare indici e file dati.

In ogni caso il metodo di gestione delle relazioni a livello fisico è trasparente.

Al giorno d'oggi la maggior parte dei sistemi di database esistenti sono di tipo relazionale.

Esistono un infinità di prodotti destinati alla creazione di sistemi di questo tipo tra cui citiamo Informix SQL, Oracle e in ultimis DB IV SQL per ambiente MsDos.

In questo fascicolo parleremo di SQL in generale senza fare riferimento a uno specifico prodotto.

Più precisamente l'SQL di cui parleremo è quello definito dall'ANSI e quindi potrebbe risultare che alcuni prodotti posseggano un SQL più ricco.

Vediamo solo di accennare ad alcuni concetti legati alla teoria dei database.

Un approfondimento sulla teoria dei database può essere seguita sui seguenti volumi:

·         An Introduction to Database systems (Vol. 1 & 2) di C.J.Date Addison Wesley : ISBN 0-201-19215-2 (vol. 1) ISBN 0-201-14474-3 (vol. 2)

·         Manuale delle basi dati di Gio Wiederhold - ETAS Libri

·         Database: concetti teorici ed applicativi di S. Misbah Deen - Franco Angeli

·         La teoria relazionale dei dati di Atzeni, Batini, De Antonellis - Boringhieri

 

1.1 Concetti generali

 

Un sistema relazionale è un database che viene visto dall'utente come una collezione di Tabelle.

La tabella (table) è l'unità di base del modello relazionale.

Molti sistemi di gestione database come DBIII ci obbligano ad avere una visione dell'insieme molto legato al livello fisico dei files che compongono il database stesso.

In pratica dobbiamo sempre considerare i file .DBF (file dati) e quelli .NDX (file d'indice).

Molti prodotti definiti come relazionali non lo sono di fatto se si considerano al loro livello interno.

Lo diventano nel momento in cui adottano un interfaccia utente SQL.

A livello di linguaggio SQL non dobbiamo preoccuparci come di fatto il sistema informativo tratta i nostri dati a livello fisico.

Possiamo semplicemente decidere di aggiungere uno o più indici per sveltire l'accesso ai dati.

Come farà SQL a utilizzarli possiamo dire che "sono fatti suoi".

In pratica il sistema informativo utilizzato ci permetterà di eseguire una suddivisione tra il livello fisico e quello logico.

Bisogna specificare che SQL è possibile utilizzarlo sia in modo interattivo che da linguaggio.

Vediamo inizialmente alcuni concetti teorici.

Dicevamo precedentemente che il database viene visto come un insieme di Tabelle.

Una tabella non è altro che un insieme di righe e di colonne dove le prime sono i record e le seconde i vari campi che intendiamo trattare.

 

                  +-------------------------------------------+

                  |                  TABELLA                   |

                  +-------+-------+---+-------+-------+-------+

        Riga 1    | campo | campo | C | campo | campo | campo |

                  +-------+-------+ O +-------+-------+-------+

        Riga 2    | Mario | Volpe | L | Roma  | Asti  | 16100 |

                  +-------+-------+ O +-------+-------+-------+

        Riga 3    | campo | campo | N | campo | campo | campo |

                  +-------+-------+ N +-------+-------+-------+

        Riga n    | ..... | ..... | A | ..... | ..... | ..... |

                  +-------+-------+---+-------+-------+-------+

 

 Facciamo subito un esempio.

Supponiamo di avere una tabella che rappresenta i clienti di una ditta XXXXX composta dal numero dell'utente (che deve essere unico), dal nome, dall'indirizzo e dalla città.

 

        TABELLA A

                      Num. # Nome     Indirizzo   Citta'

                      -------------------------------------

                      A001   Rossi    V.Roma      Torino

                      A002   Bianchi  V.Trento    Milano

                      A003   Verdi    V.Trieste   Genova

                      ....   .......  .........   ......

 

Un' altra tabella potrebbe essere relativa ai prodotti trattati dalla nostra ditta XXXXX, composta anche questa da un numero d'articolo unico, dal nome del prodotto e dal prezzo.

 

        TABELLA B

                          Num. # Articolo        Prezzo

                          -----------------------------

                          B001   Chiodo          150

                          B002   Bullone         300

                          B003   Dado            120

                          ....   .......         ...

 

Una  terza  tabella potrebbe essere quella  destinata  alla memorizzazione delle vendite.

In pratica risulterà essere una connessione delle due Tabelle precedenti.

 


        TABELLA C

                       Cliente   Articolo   Pezzi venduti

                       ----------------------------------

                       A001      B001       1500

                       A001      B002       5000

                       A001      B003       5000

                       A002      B003       1000

                       A003      B002       7000

                       A003      B003       3500

 

Le prime due Tabelle possono essere definite entità mentre la terza relazione delle prime due.

Senza fare ancora nessun riferimento al linguaggio SQL potremmo definire le Tabelle nel seguente modo.

 

                       CREA TABELLA A

                              ( NUM       CHAR(5),

                                NOME      CHAR(20),

                                INDIRIZZO CHAR(20),

                                CITTA     CHAR(20) );

 

                       CREA TABELLA B

                              ( ANUM      CHAR(5),

                                ARTICOLO  CHAR(30),

                                PREZZO    INTEGER );

 

                       CREA TABELLA C

                              ( NUM       CHAR(5),

                                ANUM      CHAR(5),

                                VENDUTI   INTEGER );

 

I dati delle tabelle precedenti potrebbero essere gestite a livello fisico mediante file dati, ed eventualmente indici, differenti.    L'implementazione  delle  Tabelle  create  come  nell'esempio precedente ci mostra come di fatto è possibile creare una descrizione logica del modello in modo indipendente dal suo livello fisico.

 

Potremmo suddividere i tipi di Tabelle in due classi.

La prima è costituito dalle Tabelle di base (base table) che sono in pratica Tabelle reali esistenti fisicamente come files e come record salvati in questi.

Al contrario il secondo tipo è costituito da Tabelle virtuali che di fatto non esistono a livello fisico ma che si mostrano all'utente come se di fatto esistessero.

Vedremo successivamente di approfondire questi concetti parlando delle Tabelle di base e delle viste (view).

Iniziamo ora a considerare le problematiche legate al query di un sistema di database.

Parleremo successivamente delle operazioni legate alla creazione e alla modifica. 

 

2. Il linguaggio SQL

 

Le funzioni del linguaggio SQL servono all'interrogazione, alla definizione, alla manipolazione e al controllo dei dati in un database relazionale.

Prima  di proseguire bisogna anche specificare che SQL è contemporaneamente  un  linguaggio d'interrogazione  per  uso interattivo che un vero e proprio linguaggio di programmazione.

Qualsiasi statement SQL che può essere usato in interattivo può essere usato anche in un programma.

Noi inizialmente vedremo SQL dal punto di vista del linguaggio interattivo.

Supponiamo di voler interrogare il database per aver visualizzato tutti i record che tra il campo cognome contengano 'ROSSI'.

Se disponessimo di una macchina capace di comprendere il nostro linguaggio dovremmo comunicargli le nostre intenzioni con una frase del tipo:

 

·         seleziona i campi NOME, COGNOME e INDIRIZZO in CLIENTI

·         dove il COGNOME è uguale a 'ROSSI'

 

In linguaggio SQL la cosa è molto simile.

 

 SELECT NOME, COGNOME, INDIRIZZO FROM CLIENTI

  WHERE  COGNOME = 'ROSSI';

 

Come dicevamo inizialmente il linguaggio SQL ci offre delle funzioni adatte alle varie elaborazioni possibili su un sistema di database.

Volendo abbinare lo scopo alle varie funzioni avremmo:

 

 

Scopo

Verbi

DDL - Data Definition Language

Create

Drop

DML - Data Manipulation Language

Insert

Update

Delete

DCL - Data Control Language

Grant

Queries

Select

 

 

Tralasciamo momentaneamente la descrizione dei verbi legati al DDL (Data Definition Language), al DML (Data Manipulation Language) e al DCL (Data Control Language) supponendo di avere già un database creato e vediamo subito il verbo,  già presentato negli esempi precedenti, legato all'interrogazione. SELECT il primo termine del linguaggio SQL che ora vedremo.

 

2.1. SELECT

 

SELECT è il verbo di base che ci permette di  eseguire interrogazioni sul sistema di database (query).

Per utilizzare nella forma più generalizzata possibile SELECT è sufficiente conoscere il solo nome della tabella da cui vogliamo estrarre informazioni.

Supponendo di avere una tabella YXZ e volendo vedere tutti i record memorizzati in questa potremmo usare:

 

    SELECT * FROM YXZ;

 

 

Tra gli argomenti successivi a SELECT ci sono i nomi dei campi,o per rimanere in tema colonne, che vogliamo visualizzare.

Il carattere * dice di visualizzare indistintamente tutti i campi.

In ogni caso dall'esempio della pagina precedente è facile capire la metodologia per specificare i nomi delle colonne da visualizzare.

 

    SELECT COL1, COL2, .... FROM ....

 

Il risultato dell'esecuzione di uno statement SELECT è la creazione di una nuova tabella la quale può essere a vita breve, esistente solo sullo schermo del terminale da cui si richiede l'esecuzione, oppure definitiva.

La forma definitiva della tabella si ottiene, come vedremo successivamente, salvandola in modo permanente.

Utilizzando gli esempi appena visti avremmo ottenuto una lista totale di tutti i record indipendentemente dai loro contenuti.

La successiva clausola può essere applicata a SELECT per definire i record che devono essere rintracciati.

 

2.2. WHERE

 

WHERE serve a definire il criterio di selezione dei record che devono essere rintracciati da SELECT.

Se avessimo una tabella XYZ del tipo:

 

                           NOME      DATA      IMPORTO

                           ---------------------------

                           Rossi     12/03/89  120.000

                           Bianchi   13/03/89   35.000

                           Verdi     13/03/89   22.000

 

applicando

 

   SELECT NOME FROM XYZ

  WHERE IMPORTO < 100.000;

 

avremmo come risultato

                                     NOME

                                     -------

                                     Bianchi

                                     Verdi

 

In pratica diremmo di selezionare dalla tabella XYZ i campi NOME dei record che hanno il campo IMPORTO minore di 100.000.

Le condizioni ammesse sono:

 

                        +---------------------+---------+

                        |      Condizione     | Simbolo |

                        +---------------------+---------+

                        | Uguale              |    =    |

                        | Parzialmente uguale | LIKE    |

                        | Maggiore            |    >    |

                        | Minore              |    <    |

                        | Maggiore o uguale   |   >=    |

                        | Minore o uguale     |   <=    |

                        | Diverso             |   <>    |

                        | Compreso tra        | BETWEEN |

                        | Negazione           | NOT     |

                        | Uguale a uno della  |         |

                        | lista (*)           | IN      |

                        +---------------------+---------+

 

Le varie condizioni usate con WHERE possono essere collegate tra loro mediante operatori logici. In altre parole potremmo creare costrutti del tipo:

 

   SELECT NOME FROM XYZ

    WHERE IMPORTO < 100.000 AND IMPORTO > 30.000;

 

oppure

 

   SELECT NOME FROM XYZ

 WHERE NOME < 'Mario’ AND IMPORTO >= 100.000;

 

e ancora

 

SELECT NOME, COGN, INDIR FROM XYZ

   WHERE PROVINCIA = 'Alessandria’ OR DATA < '02-JAN-89';

 

È possibile combinare clausole OR con quelle di AND utilizzando anche anche le parentesi rotonde contemplate dal linguaggio SQL.

 

SELECT NOME, COGN, INDIR FROM XYZ

WHERE (CITTA = 'Asti' AND IMPORTO < 100.000) OR CITTA = 'Pavia’;

 

Penso che non ci sia da aggiungere altro per quanto riguarda gli operatori per imbastire le condizioni quali <, >, >= ecc.

Alcune  spiegazioni  devono essere riportate  invece  sulle condizioni tipo LIKE, BETWEEN e IN.

Procediamo con ordine.

Mediante la specifica LIKE è possibile creare costrutti del tipo:

 

  SELECT NOME, COGN FROM XYZ

  WHERE COGN LIKE 'Rossi';

 

Utilizzare la LIKE come nell'esempio precedente è come fare

 

  SELECT NOME, COGN FROM XYZ

   WHERE COGN = 'Rossi';

 

La vera potenza di LIKE sta nella possibilità di utilizzare due tipi di caratteri jolly per testare delle uguaglianze parziali.

I  due caratteri sono precisamente '%' (percento)  e  '_' (underscore).

Il primo può valere uno o più caratteri mentre il secondo può sostituirne uno solo.

Supponendo di avere una tabella con:

 

                        +---------------------+---------+

                        |      Condizione     | Simbolo |

                        +---------------------+---------+

                        | Uguale              |    =    |

                        | Parzialmente uguale | LIKE    |

                        | Maggiore            |    >    |

                        | Minore              |    <    |

                        | Maggiore o uguale   |   >=    |

                        | Minore o uguale     |   <=    |

                        | Diverso             |   <>    |

                        | Compreso tra        | BETWEEN |

                        | Negazione           | NOT     |

                        | Uguale a uno della  |         |

                        | lista (*)           | IN      |

                        +---------------------+---------+

 

   SELECT DITTA FROM XYZ

  WHERE DITTA LIKE '%ogn%';

 


In questo caso avremmo visualizzato

 

                                  DITTA

                                  ---------

                                  Bolognini

                                  Bolognesi

                                  Bologna

                                  Bognardi

 

Il comando

 

   SELECT DITTA FROM XYZ

  WHERE DITTA LIKE '_ogn%';

 

visualizzerebbe

 

                                  DITTA

                                  ---------

                                  Bognardi

 

e ancora

 

   SELECT DITTA FROM XYZ

  WHERE DITTA LIKE '%ogn___';

 

darebbe come risultato

 

                                  DITTA

                                  ---------

                                  Bolognini

                                  Bolognesi

 

Sono anche possibili costrutti del tipo

 

 SELECT DITTA FROM XYZ WHERE DITTA LIKE 'B%';

 SELECT DITTA FROM XYZ WHERE DITTA LIKE '____';

 

Potrebbe verificarsi il caso in cui i caratteri '_' o '%' facciano parte di quello che si vuole ricercare.

Prendete ad esempio una tabella del tipo:

 

                             FLAGS         FUNCTION

                             ----------------------

                             O_RDONLY      open

                             O_RDWR        open

                             P_WAIT        spawn

                             P_NOWAIT      spawn

 

Per fare in modo che il carattere '_' non venga interpretato come carattere jolly bisogna farlo precedere da un carattere d'escape.

SQL definito dall'ANSI dispone della specifica ESCAPE da unire con LIKE per stabilire il carattere d'escape.

Ad esempio

 

   SELECT * FROM XYZ WHERE FLAGS LIKE 'O\_R%' ESCAPE '\';

 

In questo caso '\' viene interpretato da SQL come carattere d'escape e '_' come carattere effettivo da ricercare e non come carattere jolly.

 

Un altro operatore relazionale atipico (rispetto a <, > ecc.) è IN.

Mediante IN è possibile specificare una lista di valori da utilizzare come clausole di ricerca.

 

Un costrutto del tipo:

 

  SELECT * FROM XYZ WHERE DITTA IN ('Ansaldo’,'Montedison');

 

selezionerà tutte le righe in cui la colonna DITTA risulterà essere nella lista (nell'esempio solo Ansaldo o Montedison).

Potremmo ad esempio disporre di una tabella del tipo:

 

                            CLIENTE          IMPORTO

                            ------------------------

                            Rossini          50.000

                            Bolognini        30.000

                            Rossi             5.000

                            Verdi            90.000

                 

Se scrivessimo

 

 SELECT CLIENTE FROM XYZ WHERE IMPORTO IN (5000,30000,90000);

 

avremmo come risultato

 

                                     CLIENTE

                                     ----------

                                     Rossi

                                     Bolognini

                                     Verdi

 

L'ultima condizione è BETWEEN (compreso tra .... e ....).

Il comando

 

  SELECT NOME FROM XYZ WHERE PREZZO BETWEEN 50000 AND 100000;

 

è equivalente a scrivere

 

SELECT NOME FROM XYZ WHERE PREZZO >= 50000 AND PREZZO <= 100000;

 

Per definizione si assume che i valori specificati con BETWEEN siano in ordine ascendente.

Vediamo infine la negazione NOT che funziona in congiunzione con

le precedenti condizioni LIKE, BETWEEN e IN.

Ad esempio

 

  SELECT * FROM XYZ WHERE IMPORTO NOT BETWEEN 3000 AND 10000;

 

visualizzerebbe tutte le righe il cui contenuto del campo IMPORTO non è compreso tra 3000 e 10000.

Allo stesso modo

 

 SELECT * FROM XYZ WHERE NOME NOT LIKE 'Rossi';

 

mostrerebbe tutte le righe con contenuto del campo NOME diverse da 'Rossi'.

Alcuni campi di un record potrebbero valere NULL.

NULL può essere utilizzato come termine di selezione.

 

Ad esempio

 

   SELECT * FROM XYZ WHERE NOME IS NULL;

 

seleziona tutti i record che hanno NULL come campo NOME.

L'opposto è

 

  SELECT * FROM XYZ WHERE NOME IS NOT NULL;

 

Nel linguaggio SQL esistono alcune specifiche utilizzabili con SELECT atte a ordinare i dati che devono essere mostrati e a raggrupparli.

SELECT infatti visualizzerebbe le informazioni  nello stesso ordine con cui sono rintracciate.

La specifica

 

 ORDER BY [COLONNA] [ASC|DESC]

 

permette di ordinare i dati su una determinata colonna in modo ascendente (ASC) o discendente (DESC).

Disponendo di una tabella:

 

                                 NOME      CITTA

                                 -----------------

                                 Rossi     Alba

                                 Bianchi   Asti

                                 Verdi     Cuneo

                                 Alessi    Milano

 

ed eseguendo

 

   SELECT NOME FROM XYZ ORDER BY NOME ASC;

 

avremmo come risultato

 

                                     NOME

                                     -------

                                     Alessi

                                     Bianchi

                                     Rossi

                                     Verdi

 

mentre l'ordine sarebbe inverso nel caso di

 

  SELECT NOME FROM XYZ ORDER BY NOME DESC;

 

Il comando d'ordinamento non altera fisicamente le Tabelle ma influisce semplicemente sulla visualizzazione.

Vedremo l'utilizzo della specifica GROUP BY nel prossimo capitolo dopo aver introdotto gli operatori matematici.

 

2.3. Operatori matematici di SQL

 

Il  linguaggio SQL,  pur non essendo orientato al calcolo matematico, dispone della possibilità di implementazione dei normali operatori matematici utilizzabili con lo statement SELECT per calcoli sui campi.

Disponendo di una tabella del tipo:

 

                           CLIENTE     IMPORTO     IVA

                           -----------------------------

                           Rossi       100000      19000

                           Verdi       120000      22800

                           Bianchi     180000      34200

 

e impostando

 

  SELECT CLIENTE, (IMPORTO + IVA) FROM XYZ;

 

avremo come risultato

 

CLIENTE     (IMPORTO + IVA)

---------------------------

Rossi       119000

Verdi       142800

Bianchi     214200

 

In ogni caso gli operatori SQL sono i seguenti.

 

    Addizione        +

    Sotrazione      -

    Moltiplicazione *

    Divisione         /

    Conteggio       COUNT

    Massimo         MAX

    Minimo           MIN

    Media            AVG

    Somma           SUM

 

Gli operatori matematici dovrebbero essere intuitivi.

I seguenti costrutti valgono ad esempio per l'uso di questi.

 

   SELECT CLIENTE, (IMPORTO / 2) FROM XYZ;

   SELECT CLIENTE, ((IMPORTO + IVA) * 2) FROM XYZ;

 

Vediamo ora gli altri operatori.

Il primo è COUNT.

In pratica questo riporta il numero degli header rintracciati da SELECT.

Tenendo per valida la tabella precedente contenente tre righe e eseguendo

 

 SELECT COUNT(CLIENTE) FROM XYZ;

 

otterremmo 3.

 

Potremmo anche utilizzare COUNT con WHERE per sapere quante righe sono presenti:

 

  SELECT COUNT(*) FROM XYZ;

 

WHERE è applicabile anche con SELECT COUNT().

Se volessimo, ad esempio, sapere quanti clienti hanno speso più di 150.000 potremmo utilizzare:

 

   SELECT COUNT(CLIENTE) FROM XYZ WHERE IMPORTO > 150000;

 

Altri due operatori destinati a selezionare i valori massimi e minimi contenuti nei campi specificati sono MAX e MIN.

Supponendo di voler trovare l'importo minore nella tabella dei clienti:

 

 SELECT MIN(IMPORTO) FROM XYZ;

 

È possibile usare come argomento degli operatori MIN e MAX anche dei calcoli matematici.

 

    SELECT MAX(IMPORTO / 100) FROM XYZ;

 

L'operatore  SUM  è applicabile solo a campi numerici  e restituisce la somma dei valori contenuti in questi.

 

 SELECT SUM(IMPORTO) FROM XYZ;

 

restituisce la somma di tutti gli importi presenti nella tabella (sempre quella riportata ad esempio nelle pagine precedenti).

Se dovessimo calcolare una media di tutti gli importi presenti nella tabella potremmo dare il comando:

 

SELECT (SUM(IMPORTO) / COUNT(IMPORTO)) FROM XYZ;

 

In pratica verrebbe calcolata la somma di tutti gli importi presenti nella tabella e successivamente divisa per il numero delle righe conteggiate.

Il linguaggio SQL possiede un operatore particolare che permette di  calcolare la media senza dover eseguire calcoli  come nell'esempio precedente.

L'operatore è AVG.

Usandolo l'esempio precedente diventerebbe :

 

 SELECT AVG(IMPORTO) FROM XYZ;

 

Esiste un’ulteriore specifica utilizzabile con l'operatore COUNT è DISTINCT.

Una determinata colonna potrebbe contenere dei valori duplicati.

Se si desidera avere il conteggio non considerando i duplicati è possibile creare costrutti del tipo:

 

  SELECT COUNT(DISTINCT CLIENTE) FROM XYZ;

 

Supponiamo di avere una tabella XYZ contenente l'elenco delle vendite di un determinato anno.

 

                         CLIENTE     IMPORTO    DATA

                         -------------------------------

                         Rossi       10000      12/12/89

                         Bianchi     20000      12/12/89

                         Verdi       12000      12/12/89

                         Rossi       30000      13/12/89

                         Rossi       34000      15/12/89

 

Mediante

SELECT COUNT(CLIENTE) FROM XYZ;

 

avremmo come risultato il numero delle righe (record) presenti nella tabella ovvero 5.

Desiderando sapere il numero delle ditte a cui è stato venduto del materiale dovremmo dare:

 

  SELECT COUNT(DISTINCT CLIENTE) FROM XYZ;

 

Avremmo come risultato 3.

 

Altre tre funzioni di utilità non elencate tra gli operatori precedenti sono LOWER, UPPER e LENGTH.

Il contenuto delle righe ricercate potrebbe essere vario.

Il nome di una ditta potrebbe risultare come "Rossi", come "ROSSI" o ancora come "rossi".


Se avessimo una tabella con:

 

                               CLIENTE    IMPORTO

                               ------------------

                               Rossi      100000

                               Verdi      120000

                               Bianchi    130000

 

e cercassimo di rintracciare qualche riga con

 

SELECT CLIENTE FROM XYZ WHERE CLIENTE = 'ROSSI';

 

non troveremmo nulla dato che il linguaggio fa differenza tra caratteri maiuscoli e minuscoli e quindi "Rossi" risulta essere differente da "ROSSI".

Le funzioni LOWER e UPPER ci permettono di convertire i valori delle colonne rintracciate da SELECT in minuscolo e in maiuscolo. Non avendo la sicurezza sul tipo di caratteri contenuti in un campo potremmo usare:

 

   SELECT UPPER(CLIENTE) FROM XYZ WHERE CLIENTE = 'ROSSI';

 

oppure

 

   SELECT LOWER(CLIENTE) FROM XYZ WHERE CLIENTE = 'rossi';

 

La funzione LENGTH restituisce invece la lunghezza di ogni riga.

 

SELECT LENGTH(CLIENTE) FROM XYZ;

 

In pratica conta i caratteri di ogni campo.

Nel capitolo precedente avevamo rimandato il discorso legato all'utilizzo della specifica GROUP BY.

Per introdurre il concetto di raggruppamento possiamo vedere un esempio pratico.

Supponiamo di avere una tabella del tipo:

 

                             PRODOTTO  TIPO     QUANTITA

                             ---------------------------

                             Chiodi    1        20000

                             Bulloni   1        12000

                             Dadi      1        17000

                             Chiodi    2        10000

 

   Se desiderassimo conoscere il numero totale dei pezzi presenti indipendentemente dal tipo del prodotto potremmo usare:

 

 SELECT SUM(QUANTITA) FROM XYZ;

 

Nel caso in cui ci interessasse sapere quanti chiodi abbiamo possiamo usare:

 

SELECT PRODOTTO, SUM(QUANTITA) FROM XYZ WHERE PRODOTTO='Chiodi';

 

Se  volessimo avere visualizzate tutte le somme dei pezzi raggruppati per tipo, allora:

 

  SELECT PRODOTTO, SUM(QUANTITA) FROM XYZ GROUP BY PRODOTTO;

 

Il risultato sarebbe

 

                            PRODOTTO   SUM(QUANTITA)

                            ------------------------

                            Chiodi     30000

                            Bulloni    12000

                            Dadi       17000   

 

Parlando  del WHERE avevamo visto come questo servisse ad eliminare dalla selezione le righe.

WHERE non è applicabile a GROUP BY.

Nel caso in cui si vuole eliminare alcuni gruppi è possibile utilizzare la specifica HAVING.

È possibile ad esempio creare costrutti del tipo:

 

  SELECT CAMPO1 FROM XYZ GROUP BY CAMPO2 HAVING COUNT(*) > 1;

 

3. Tabelle

 

Fino a questo punto abbiamo visto come ricercare dati da una determintata tabella.

In altre parole abbiamo considerato una tabella come un archivio in cui sono memorizzati dei dati e mediante SELECT abbiamo estratto i dati che ci interessavano.

Un sistema di database relazionale viene considerato come una raccolta di Tabelle e quindi la visione che abbiamo deve essere espansa.

I concetti generali li avevamo accennati inizialmente.

Utilizzando lo statement SELECT abbiamo specificato il nome delle colonne scrivendo semplicemente il suo nome non preoccupandoci invece di definire la tabella in cui queste erano contenute in quanto, di fatto, gli esempi erano sempre e solo relativi a una singola tabella.

Un determinato nome di colonna potrebbe essere comune a più Tabelle.

Nel caso in cui SELECT deve ricercare dati da più Tabelle è chiaro che se specificassimo solo il nome di un campo potrebbe trovarsi nei pasticci, proprio per il fatto che la colonna potrebbe essere definita in più Tabelle.

SQL al fine di evitare questo tipo di problemi accetta la specifica del nome di colonna preceduto da nome della tabella in cui si trova questo.

Al fine di portare un esempio a quanto detto prima possiamo supporre di avere le seguenti due Tabelle.

 

                TABELLA AAA      NOME   INDIRIZZO

                                ----------------

                                Rossi  V.Roma

                                .....  ......

 

                TABELLA BBB      NOME   IMPORTO

                                ----------------

                                Rossi  100000

                                .....  ......

 

Volendo eseguire un costrutto con SELECT potremmo scrivere:

 

  SELECT AAA.NOME, BBB.NOME FROM AAA, BBB;

 

Tutti gli statement in cui si richiedono colonne da due o più Tabelle vengono chiamati JOIN.

In pratica gli operatori JOIN sono quelli che distinguono un database relazionale da uno non relazionale.

La sintassi di quanto detto prima è:

 

 SELECT tabella1.campo, tabella2.campo ... FROM tabella1,tabella2;

 

L'esempio  precedente  avrebbe  creato  come  risultato  la visualizzazione di tutte le combinazioni possibili tra il campo NOME di AAA e quello NOME di BBB.

La specifica WHERE è utilizzabile anche in questo caso al fine delle righe dalla visualizzazione.

 


È possibile creare costrutti del tipo:

 

 SELECT AAA.*, BBB.* FROM AAA, BBB WHERE AAA.NOME = BBB.NOME;

 

oppure utilizzando anche più Tabelle

 

 SELECT A.CITTA, B.NOME, C.IMPORTO FROM A, B, C;

 

SQL permette di assegnare un nuovo nome alle Tabelle di un determinato statement.

L'operazione è normalmente conosciuta come ALIAS.

Una tabella ALIAS rimane attiva solo durante l'esecuzione dello statement.

Lo standard ANSI riconosce ALIAS con il nome di correlazione.

 

SELECT A.*,B.* FROM TABELLA1 A, TABELLA2 B WHERE A.CAMPO = B.CAMPO;

 

Assegna come ALIAS il nome A alla TABELLA1 e B alla TABELLA2.

 

4. Subquery

 

Per introdurre il concetto rivediamo l'utilizzo della specifica IN.

Avevamo detto che questo controlla se un valore è presente in una lista.

In altre parole il predicato IN formulato con:

 

  campo IN (a, b, c, ...);

 

è equivalente a

 

 campo = a OR campo = b OR campo = c OR ... ;

 

I valori della lista potrebbero essere quelli selezionati da uno statement SELECT e cioè potremmo fare una sottointerrogazione per ricavare i dati della lista che ci interessano.

Ad esempio potremmo usare:

 

 SELECT NOME,INDIRIZZO FROM XYZ WHERE NOME IN  (SELECT NOME FROM ZYX WHERE CITTA = 'Asti');

 

Il SELECT tra parentesi selezionerebbe tutti i campi NOME della tabella ZYX che possiedono come città 'Asti'.

Il primo SELECT visualizzerebbe i campi NOME e INDIRIZZO di tutte le righe il cui NOME è presente nella lista creata dal costrutto precedente.

Sono anche possibili statement del tipo:

 

    SELECT NOME, INDIRIZZO FROM TABELLA1 WHERE CITTA IN

  (SELECT CITTA FROM TABELLA2 WHERE NUMERO IN

   (SELECT NUMERO FROM TABELLA3 WHERE IMPORTO > 50000));

 

oppure

 

 SELECT NOME FROM TABELLA1 WHERE CITTA = 'Asti' AND IMPORTO IN

   (SELECT IMPORTO FROM TABELLA2 WHERE IMPORTO > 50000);

 

 Come avete sicuramente notato negli esempi precedenti è stata utilizzata la specifica IN.

Se utente sa che una determinata sotto-interrogazione ritorna esattamente un solo valore può utilizzare un normale operatore di confronto (=, >, <, ecc.).

Ad esempio:

 

   SELECT NOME FROM TABELLA1 WHERE CITTA =

(SELECT CITTA FROM TABELLA2 WHERE NOME = 'Rossi');

 oppure

  SELECT NOME FROM TABELLA1 WHERE IMPORTO <

    (SELECT MAX(IMPORTO) FROM TABELLA2);

 

Terminiamo  questa panoramica sulle interrogazioni guardando ancora il concetto di unione.

 

Due interrogazioni con SELECT possono essere unite al fine di creare una tabella unica.

Il vocabolo che permette di eseguire questa funzione è UNION la cui sintassi è:

 

  SELECT .... FROM tabella1 UNION SELECT .... FROM tabella2;

 

Il seguente esempio crea una tabella che è la somma delle due create dai comandi SELECT.

 

    SELECT * FROM TABELLA1 UNION SELECT * FROM TABELLA2;

 

Nel caso che si vogliano eseguire più di due interrogazioni è necessario utilizzare le parentesi rotonde per la suddivisione.

Un esempio:

 

 SELECT NOME FROM TABELLA1 UNION

 (SELECT NOME FROM TABELLA2 UNION SELECT INDIRIZZO FROM TABELLA3);

 

Con  questo  abbiamo  concluso  il  discorso  legato  alle interrogazioni.

Avremmo potuto iniziare la trattazione di SQL partendo dalla creazione, cancellazione e modifica dei records in un sistema di database.

Ho preferito iniziare dalle interrogazioni lasciando la parte relativa alle modifiche, creazione inclusa, per ultima.

In questo modo chi legge questo fascicolo incomincia a chiarirsi le  idee manipolando oggetti già costruiti senza  dovere, inizialmente, sforzarsi a immaginarsi come possono essere creati questi oggetti.

Proseguiremo ora con alcuni argomenti legati all'utilizzo dei prodotti già creati.

 

5. View

 

Inizialmente parlando di Tabelle avevamo fatto una distinzione.

In pratica avevamo detto che potevamo classificare queste in due classi differenti: le TABELLE di BASE e le TABELLE VIRTUALI.

Le prime sono quelle che esistono realmente e che quindi occupano uno spazio fisico di memoria.

Queste vengono create con il comando SQL, visto in un esempio iniziale e discusso successivamente, CREATE TABLE.

Il secondo tipo di Tabelle in realtà non esistono fisicamente ma soltanto virtualmente e quindi non occupano spazio nel database.

Questo tipo di Tabelle vengono definite in SQL come VIEWS (viste) e appaiono all'utente come se fossero reali.

È possibile creare Tabelle di questo tipo con determinate condizioni, ad esempio per fare in modo che l'utente veda solo nella tabella tutti i record di quelli che abitano in una certa città.

Una VIEW può essere creata con le parole CREATE VIEW.

Il contenuto di una VIEW viene scritta da uno statement SELECT utilizzato nel seguente modo:

 

    CREATE VIEW PROVA AS SELECT .... ;

 

Fate attenzione che il nome della VIEW non sia in conflitto con quello di qualche tabella reale.

Le colonne di una VIEW possono essere specificati oppure copiati mediante i campi specificati in SELECT.


Prendiamo ad esempio:

 

  CREATE VIEW PROVA AS SELECT * FROM TABELLA1;

 

Lo statement crea una tabella virtuale, VIEW, chiamata PROVA contenente tutte le colonne (vedi '*' di SELECT) contenute nella TABELLA1.

 

CREATE VIEW PROVA ( NM, IMP ) AS

    SELECT NOME, IMPORTO FROM TABELLA1;

 

Il precedente costrutto invece definisce la struttura della VIEW contenente i campi NM e IMP corrispondenti con quelli NOME e IMPORTO della tabella di base TABELLA1.

I nomi delle colonne di una VIEW devono essere specificati in modo esplicito nel caso in cui nello statement SELECT ci sia una funzione di tipo matematico oppure SUM, MAX ecc.

Ad esempio:

 

CREATE VIEW PROVA (NM, TOTIMP) AS

   SELECT NOME, SUM(IMPORTO) FROM TABELLA1;

 

Un altro esempio potrebbe essere

 

CREATE VIEW PROVA (NM, TOTIMP) AS

  SELECT NOME, (IMPORTO + IVA) FROM TABELLA;

 

Sono anche possibili costrutti del tipo:

 

   CREATE VIEW PROVA AS

   SELECT NOME, IMPORTO FROM TABELLA1 WHERE CITTA = 'Asti';

 

Ricordandosi quanto detto a riguardo della natura virtuale della VIEW possiamo analizzare l'esempio precedente per fare alcune considerazioni aggiuntive.

Quando CREATE VIEW viene eseguito lo statement SELECT-FROM-WHERE non è di fatto eseguito ma semplicemente salvato nel catalogo.

L'utente in ogni caso vede la VIEW creata come se fosse una tabella reale.

In questo caso disporrà di una tabella PROVA che può essere considerata come una finestra nella tabella reale dalla quale la VIEW deriva.

Le operazioni di update della view sono riflesse sulla tabella originale anche se di fatto bisogna tenere a mente che non sempre le VIEW sono updatabili.

Vedremo successivamente il perchè di questa affermazione dopo aver visto le operazioni di INSERT, UPDATE ecc.

L'utilità di una VIEW è legata ad alcuni aspetti quali ad esempio la possibilità di mostrare gli stessi dati ad utenti in modo differente oltre ad alcune metodologie utilizzate per la ristrutturazione dei database.

La rimozione di una vista può essere eseguita semplicemente utilizzando il comando:

 

    DROP VIEW NOMEVIEW;

 

6. Modifica record

 

Fino a questo punto abbiamo visto soltanto la parte di linguaggio SQL adatto all'interrogazione.

Lavorando su database spesso ci si ritrova nella necessità di apportare modifiche ai contenuti dei records.

SQL dispone del verbo UPDATE che ci permette di svolgere questo tipo di azioni.

La sintassi generalizzata è:

 

  UPDATE TABELLA SET .... ;

Un comando del tipo

 

    UPDATE TABELLA1 SET NOME = 'Rossi';

 

setterebbe tutti i record della TABELLA1 inserendo nella colonna NOME il nome 'Rossi'.

Update può essere in questo caso veramente pericoloso dato che ha la possibilità di cambiare tutti i record di una tabella.

La clausola WHERE può restringere il campo dei dei record su cui agire.

Ad esempio

 

  UPDATE TABELLA1 SET NOME = 'Rossi' WHERE NOME = 'Bianchi';

 

rintraccerebbe le righe della tabella in cui il campo NOME contiene 'Bianchi' e sostituirebbe questo con 'Rossi'.

Supponiamo di avere un database della SIP in cui vengono memorizzati i dati relativi alla rete telefonica.

Una tabella potrebbe essere:

 

        TABELLA NUMERI

                          NUMERO       ZONA     ARMADIO

                          -----------------------------

                          223456       131      A-123

                          223457       131      A-123

                          223459       131      A-123

                          223462       131      A-123

                          985685       131      A-123

                          985686       131      A-123

 

Supponiamo a questo punto che i numeri inizianti per 22.. debbano essere aggiornati seconda la nuova numerazione.

In pratica dovrebbero avere un incremento di 762231 per fare in modo che il numero 223456 diventi 985687 e cosi via.

Il comando per l'update potrebbe essere:

 

 UPDATE NUMERI

 SET NUMERO = NUMERO + 762231

  WHERE NUMERO > 223455 AND NUMERO < 223463;

 

Mediante UPDATE non è possibile cambiare records da più di una tabella per volta.

 

Includo tra i verbi adatti a modificare un record anche quelli legati all'inserimento e alla cancellazione.

Il verbo SQL che permette di creare un nuovo record è INSERT la cui sintassi generalizzata è:

 

  INSERT INTO TABELLA .... ;

 

I valori da inserire devono essere specificati tra parentesi dopo la parola VALUE.

Guardate il seguente esempio:

 

  INSERT INTO TABELLA VALUE(1,'Rossi','V.Roma’,'Asti',100000);

 

Utilizzando il metodo appena descritto dovremo assegnare tutti i campi del record che intendiamo inserire.

Nel caso in cui volessimo solo assegnare alcuni campi dovremmo specificare questi prima di utilizzare la parola VALUE.

Prendiamo l'esempio precedente e consideriamolo un’assegnazione di tutti i campi.

Questi potrebbero essere:

 

   NUMERO, NOME, INDIRIZZO, CITTA, IMPORTO

 

Se volessimo solo assegnare il campo nome e quello relativo all'importo potremmo fare:

 

  INSERT INTO TABELLA (NOME, IMPORTO) VALUES ('Rossi',100000);

 

Il valore NULL può essere utilizzato come valore.

In ogni caso l'assegnazione può anche non essere diretta ma frutto di un’interrogazione eseguita mediante SELECT a patto che questa non sia eseguita sulla stessa tabella in cui si vuole inserire il valore.

C'è da notare che usando la specifica VALUE si crea un solo record mentre utilizzando SELECT viene creato un record per ogni valore restituito.

Vediamo alcuni esempi in pratica:

 

    INSERT INTO TABELLA1 (NOME, IMPORTO)

    SELECT NOME, IMPORTO FROM TABELLA2;

 

oppure anche con WHERE:

 

    INSERT INTO TABELLA1 (NOME, IMPORTO)

   SELECT NOME, IMPORTO FROM TABELLA2 WHERE CITTA = 'Romà;

 

La cancellazione di un record avviene mediante DELETE.

 

    DELETE FROM TABELLA;

 

cancella tutti i record della tabella.

Nel caso in cui si vogliono selezionare i records da cancellare bisogna utilizzare la parola WHERE.

 

  DELETE FROM TABELLA WHERE NOME = 'Rossi' AND CITTA = 'Roma’;

 

7. Creazione Tabelle

 

Dopo aver visto le metodologie per eseguire interrogazioni sulle Tabelle diamo un occhiata finalmente al modo di crearle.

Penso che a questo punto sia abbastanza chiaro che cosa si intende per tabella.

La creazione avviene con la parola CREATE usata nel seguente modo:

 

   CREATE TABLE (CAMPO1, CAMPO2, ....);

 

Le specifiche tra parentesi sono in pratica i nomi dei campi che si vogliono avere nella tabella seguiti dalla specifica del tipo che tra poco vedremo.

I nomi dei campi non possono essere parole riservate di SQL.

Prima di vedere la tipologia dei campi facciamo un esempio.

 

CREATE TABLE (CAMPO1 CHAR(20), CAMPO2 NUMBER(5));

 

Vediamo i tipi validi.

Voglio premettere che la seguente tipologia è quella di Informix SQL e che quindi in altri prodotti potrebbe essere più ridotta o più espansa.

In ogni caso consiglio la consultazione del manuale del prodotto specifico che utilizzate.


 

        TIPO         NOTE

        ----------------------------------------------------------------

        CHAR(n)            Una stringa di caratteri lunga n.

                           n deve essere >= 1 e <= 32.767

        SMALLINT           Un numero tra -32.767 e +32.767

        INTEGER            Un numero tra -2.147.483.647 e +2.147.483.647

        DECIMAL[(m[,n])]   Un numero in virgola mobile con m valori

                           significativi  (m  <=  32)  e  con  n  valori

                           decimali.

        SMALLFLOAT         Un numero in virgola mobile corrispondente al

                           tipo float del linguaggio C

        FLOAT              Un numero in virgola mobile corrispondente al

                           tipo double del linguaggio C

        MONEY[(m[,n])]     Un numero decimale che indica una cifra di

                           soldi visualizzata con il simbolo $.

        SERIAL[(n)]        Un     numero    sequenziale     assegnato

                           automaticamente da SQL.

        DATE               Una

 

In  alcuni  casi si desidera che un determinato campo non  possa assumere il valore NULL.

Se si desidera che SQL richieda in modo obbligatorio 'inserimento di un campo e' possibile specificare a seguito  del tipo la parola NOT NULL.

Nel caso in cui avviene questa specifica SQL segnalerà un messaggio d'errore tutte le volte che si cercherà di omettere l'inserimento.

 

Un esempio:

CREATE TABLE TABELLA (

    IDNUM  CHAR(5) NOT NULL,

    NOME   CHAR(20),

    INDIR  CHAR(20),

    IMPORTO INTEGER);

 

L' assegnazione al campo IDNUM è obbligatorio.

Se si desidera che il valore di una determinata colonna sia unico in tutta la tabella è possibile specificare la word UNIQUE.

Fate attenzione che UNIQUE può essere specificato solo con quei campi che sono anche stati definiti come NOT NULL.

Riprendendo l'esempio precedente:

CREATE TABLE TABELLA (

    IDNUM  CHAR(5) NOT NULL UNIQUE,

    ......  .........

);

Nel caso in cui i campi da definire come UNIQUE siano più di uno è  possibile  eseguire la specifica anche in fondo  alla dichiarazione.

Prendiamo il seguente esempio:

 

CREATE TABLE TABELLA (

    IDNUM  CHAR(5) NOT NULL UNIQUE,

    DITTA  CHAR(20) NOT NULL UNIQUE,

    PIVA   CHAR(11) NOT NULL UNIQUE

);

 

potrebbe essere definita anche come:

 

CREATE TABLE TABELLA (

    IDNUM  CHAR(5) NOT NULL,

    DITTA  CHAR(20) NOT NULL,

    PIVA   CHAR(11) NOT NULL,

    UNIQUE  (IDNUM,DITTA,PIVA)

);

 

È possibile eliminare una tabella mediante

 

    DROP TABLE NOMTAV;

 

Quando viene creata una tabella e successivamente si esegue un inserimento i dati vengono accodati a quelli già presenti senza che venga dato un preciso ordine.

Se i records sono molti la ricerca e l'accesso ai dati può diventare estremamente lento.

Per sveltire le operazioni di interrogazione possono essere creati e utilizzati gli indici.

Se si richiede la creazione di un indice SQL esegue la copia, questa volta ordinandoli, dei dati in un altro file (indice).

La copia dei dati non è completa ma soltanto dei campi o delle parti di questi specificati come chiavi per la ricerca.

 

A questi vengono associati dei puntatori al file di dati in modo tale che se si richiede una ricerca SQL utilizza il nuovo file e mediante questi rintraccia l'ubicazione precisa del record nel file principale.

Il trattamento degli indici avviene mediante un algoritmo di B-Tree di cui non discuteremo in questo testo.

SQL è in grado di accorgersi automaticamente dell'esistenza di un determinato indice e quindi di utilizzare questo per il rintracciamento dei dati al posto della ricerca sequenziale nel file .DAT.

Come avevamo detto precedentemente l'uso degli indici da parte di SQL può essere completamente trasparente all'utente.

Molti prodotti come INFORMIX SQL richiedono, durante la procedura interattiva di creazione delle Tabelle, se i vari campi devono possedere un indice associato e se questo può contenere chiavi duplicate. La creazione da interprete di un indice può avvenire mediante:

 

 CREATE INDEX NOMIND ON TABELLA(CAMPO1, ....);

 

Se disponessimo di una tabella TABELLA1 con i seguenti campi

 

 NOME, INDIRIZZO, PIVA, IMPORTO

 

potremmo, ad esempio, creare un indice utilizzando come chiave NOME+PIVA.

 

 CREATE INDEX NEWINDEX ON TABELLA1(NOME, PIVA);

 

Se avessimo scelto di creare un indice in modo che in questo non possano risultare dupplicazioni avremmo dovuto utilizzare la parola SQL UNIQUE nel seguente modo:

 

   CREATE UNIQUE INDEX NEWINDEX ON TABELLA1(NOME, PIVA);

 

L'eliminazione di un indice si ottiene mediante

 

    DROP INDEX NOMIND;

 

7.1. Privilegi sulle Tabelle

 

Quando si accede a una macchina fornita di un sistema operativo multiutente bisogna eseguire la procedura di login durante la quale l'utente viene identificato con un nome associato a quell'accesso.

Se si dispone di un sistema di database installato su una macchina multiutente  esiste quasi sicuramente la possibilità che più persone possano lavorare vicino a questo, magari anche contemporaneamente.

Chiaramente, in questo caso, si deve regolamentare i permessi d'accesso alle Tabelle per fare in modo che ogni persona faccia esattamente quello che deve, o che può, fare senza correre il pericolo che avvengano modifiche o operazioni non gradite sulle Tabelle da parte di persone estranee o non autorizzate.

Colui che crea un certa tabella può stabilire quali operazioni possono essere eseguite.  SQL dispone della funzione GRANT destinata a questa operazione.

La sintassi generalizzata è:

 

 GRANT lista[ALL] ON tabella TO lista[PUBLIC];

 

Ad esempio:

 

 GRANT ALL ON TABELLA1 TO PUBLIC;

 

permette  a chiunque di eseguire qualsiasi statement sulla TABELLA1.

 

  GRANT INSERT, SELECT ON TABELLA1 TO MARIO;

 

permette l'inserimento e il query all'utente identificato come Mario.

 

 GRANT UPDATE(NOME,IMPORTO) ON TABELLA1 TO MARIO;

 

permette a Mario di modificare i campi NOME e IMPORTO di TABELLA1.

 

  GRANT ALL ON TABELLA1 TO MARIO,LUCY,FRANCO;

 

permette l'esecuzione di tutti gli statement a Mario, Lucy e a Franco.

La revoca dei permessi può essere eseguita con il verbo REVOKE.

Ad esempio:

 

REVOKE ALL ON TABELLA1 FROM MARIO;

 

rimuove tutti i diritti a Mario.

 

   REVOKE INSERT ON TABELLA1 FROM MARIO;

 

rimuove il permesso d'inserimento a Mario.

 

8. Fine

 

Con questo concludo questo breve fascicolo tralasciando tutta il trattamento dei report, dei form ecc.

Oltre tutto in questa parte è stata omessa la parte legata alla programmazione con SQL.

Tutto questo è presente nella seconda parte di questo testo che verrà utilizzato come dispensa per un corso che dovrò tenere tra circa due mesi e che quindi non è ancora possibile lasciare tra il materiale PUBLIC DOMAIN.

In ogni caso, come già detto precedentemente, le informazioni qui riportate sono generalizzate e non si attengono a qualche prodotto specifico anche se in alcuni casi, ad esempio parlando della tipologia dei dati, mi sono legato a Informix SQL.

La seconda parte del fascicolo è invece volutamente legata a questo prodotto del quale si guarderanno anche altri aspetti.

Data la scarsa documentazione esistente in italiano su SQL penso che il breve testo sia potuto servire a coloro che desideravano introdursi al  fine di cercare di capire quali sono  le possibilità di un linguaggio come questo.

 


 

 

(C) Copyright 1989 Flavio Bernardotti - Montecastello

Tel. 0131-355506 (Dati) 0131-355529 (Voce)

Via Trento, 10 - 15040 Montecastello (Al.)

 

SQL è un marchio registrato dell' I.B.M. Inc.

INFORMIX è un marchio registrato dell' INFORMIX Software Inc.

 

 

Nota non relativa al Linguaggio SQL

 

Il seguente testo è da considerarsi PUBBLICO DOMINIO per scopi non commerciali.

 

--------------------------------------------------------------------------------------------------------

Non è assolutamente permesso a ditte che si occupano di formazione professionale di utilizzare questo testo per fornire dispense nei corsi da loro tenuti.

Non è neppure permesso copiare, anche solo parzialmente, il testo.

--------------------------------------------------------------------------------------------------------

 

Voglio sottolineare queste condizioni in quanto con testi da me scritti precedentemente si è verificata la sostituzione del copyright originale con quello delle ditte che li utilizzavano per i fatti loro.

Purtroppo chi è vicino all'informatica per passione, anche a livello amatoriale, quasi sempre non immagina che il mondo professionale è spesso costituito da molti "mangia-mangia" (per fortuna non tutti) che non si fanno scrupoli quando si tratta di prendere un programma e di sostituirgli il copyright per poi rivenderlo come farina del loro sacco.

Lo spirito filosofico che sostiene il PUBLIC DOMAIN, le reti amatoriali come la FidoNet, la Sublink, viene spesso devastato da quelle  persone  che hanno il coraggio di definirsi  come "informatici" ma la cui visione di questa non va oltre al concetto di "fattura al cliente", costi quel che costi, anche a discapito di altre organizzazioni che basano la loro attività sul lavoro serio.

D'altra parte si sa che quando si tratta di software la spesa maggiore è quella legata alla progettazione, alla realizzazione e alla messa a punto.

Rubare un pacchetto di contabilità (per fare un esempio) elimina tutte e tre le fasi permettendo di passare subito alla quarta e cioè all'emissione della fattura al cliente. Lo stesso vale per molte ditte che si occupano di formazione professionale.

Queste spesso organizzano corsi di 30 ore con un numero minimo di 10 persone richiedendo importi che variano da 1.500.000 a più di 2.500.000 a persona.

Capite che un corso del genere permette di ricavare una media di 20.000.000 che tolto circa un 30% di tasse, 60.000 all'ora date al docente e 200.000 di spese varie si riducono a soli 12.000.000 di guadagno pulito per la società fatti i circa 6 giorni di lavoro.

Volete che questa spenda ancora 50.000 per iscritto al fine di fornirgli un volume di testo o che prendano uno e lo facciano stare un mese a scrivere e a comporre le dispense ? No !

È più comodo, veloce e si spende di meno a prendere tra gli scritti che circolano tra il pubblico dominio, cambiargli il copyright e fornirgli quelli. Voglio precisare che quello che ho detto non nasce da pure teorie astratte ma da esperienza personale fatta su casi realmente accaduti.

 

Alzi la mano chi di voi non è a conoscenza di qualche speculazione fatta mediante software rubato.

 

Il fascicolo è da considerasi come una semplice introduzione al linguaggio  SQL per tutti quelli che vogliono  avvicinarsi all' ottica della gestione dei database mediante questo.

Voglio precisare che la dispensa composta dalla parte 1 (questa) e dalla parte 2 (non ancora rilasciata tra il PD soft) è stata scritta per un corso legato all'utilizzo di SQL e di Informix SQL.

In ogni caso un ulteriore approfondimento può essere eseguito sui manuali specifici del prodotto SQL utilizzato anche non Informix.

 

Top