PRINCIPALE > SOFTWARE E STRUMENTI DI PROGRAMMAZIONE

Eseguire una ricerca veloce nell' archivio delle risorse di Visual Basic Italia®: 

Preso dall'archivio...

Premere il pulsante sotto per accedere direttamente ad un articolo o ad un esempio preso in modo casuale dall'archivio.



Ultimo e-book pubblicato:

"INTRODUZIONE AI CSS"

Lo scopo del CSS language è quello di controllare lo stile dei vari elementi che concorrono a formare un
documento HTML.
Si può operare in tre modi collegamento ad un foglio di stile esterno;definizione degli stili all'inizio
del documento utilizzo della proprietà style all'interno di un Tag HTML (embedded style). Questo e-book introduttivo
servirà per apprendere tali nozioni fondametali dei fogli di stile.

Prezzo: € 0.0.
Presentazione:
REAL SOFTWARE RILASCIA LA VERSIONE 5.0 di REALbasic per Windows






Gorizia, 5 maggio 2003 - Active, distributore in esclusiva di REALSoftware, Austin, Tx, annuncia la disponibilità di REALbasic 5.0 per Windows, uno strumento per lo sviluppo semplice da usare che permette agli utenti Windows di tutti i livelli di creare applicazioni personalizzate e di compilarle sia per la piattaforma Windows che per quella Macintosh.
[>>]

http://www.active-software.com

 

Contatti. Utilizzare l'email generica per domande relative al sito:
Porre domande relative al sito
oppure scrivere ad un responsabile di area.
Responsabile del sito: >Andrea Martelli
Responsabile area "Corso di VB":
> Giorgio Abraini

Lezioni di Database (a cura di Paolo Malesci): Database relazionali ed SQL

Questa lezione, consultata da 31644 utenti, è stata giudicata di ottimi contenuti , con un'esposizione perfettamente comprensibile e con un livello di approfondimento ottimo da 159 votanti.


I Database relazionali

Un Db si dice relazionale quando al suo interno è possibile stabilire relazioni tra sottoinsiemi di dati.
Facciamo un esempio: abbiamo 2 files, nel N.1 ci sono i dati di tutti gli impiegati di una Società, nel N.2 ci sono i dati di tutti i reparti della Società; se nel record tipo 1 è presente il reparto di appartenenza allora possiamo mettere in relazione gli impiegati con i rispettivi reparti.
Naturalmente l'esistenza di relazioni pone delle restrizioni: modifiche all'identificativo dei record tipo 2 o loro cancellazione provoca la distruzione della relazione.
Un primo passo verso il Db relazionale nell'ambito Personal Computer fu l'introduzione sia per il dBaseIII che per il Silver-Fox del comando SET RELATION TO .
Vediamone l'uso e le limitazioni.

Si usavano delle aree di lavoro, in ognuna delle quali era possibile aprire un solo Db per volta; la sequenza dei comandi sarebbe stata:

SELECT 1 sceglie l'area 1
USE REPARTI INDEX REPARTI apre REPARTI.DBF con indice REPARTI.NDX (IDX per Silver-Fox)
SELECT 2
USE IMPIEGAT INDEX IMPIEGAT
SET RELATION TO REPARTO ON REPARTI

col vincolo che il campo REPARTO esistesse in entrambi e con lo stesso formato ed inoltre fosse la Chiave dell'indice in uso per REPARTI
Allora per ogni record di IMPIEGATI erano disponibili, oltre ai campi di quel Db, anche i campi del Db REPARTI:
ad esempio A–>NOMEREP, dove A–> indicava l'Alias del Db: A=area 1, B=area 2, etc..

Non era molto ma si incominciava ad introdurre il concetto.
Anche perché nel frattempo erano nati i primi veri Db relazionali, ma la complessità dei loro motori li confinava su macchine più grandi e potenti: poveri PC con i loro 640Kb di RAM!.
Uno di quei primi Db relazionali è ancora oggi vivo e vegeto ed è Oracle, ma il requisito minimo per utilizzarlo è un server Windows NT ed alcune decine di milioni per la licenza.

Quindi d'ora in avanti ci limiteremo a Database relazionali che siano compatibili con i nostri PC, in particolare Microsoft Access (ed il relativo motore: MS Jet) che, pur non essendo l'unico, ha praticamente monopolizzato il mercato in ambiente Windows. Pur essendo nato sotto Windows 3.1 la sua diffusione su larga scala è iniziata con Windows 95 e la sua integrazione nel pacchetto MS Office.

SQL - Structured Query Language

La sua nascita è dovuta all'esigenza di stabilire una interfaccia standard di accesso ai Database indipendentemente dal tipo e dalla piattaforma.
Esamineremo in dettaglio l'SQL supportato dal motore MS Jet (quello dei Data Access Object di Visual Basic) e dei comandi SQL ignoreremo in genere quelli non utilizzabili in Visual Basic.

» SELECT Statement
Ordina al motore Microsoft Jet di recuperare informazioni da un database sotto forma di un insieme di records.
Sintassi:

SELECT [predicate] { * | table.* | [table.]field1 [AS alias1] [, [table.]field2 [AS alias2] [, ...]]}
FROM tableexpression [, ...] [IN externaldatabase]
[WHERE... ]
[GROUP BY... ] [HAVING... ]
[ORDER BY... ]
[WITH OWNERACCESS OPTION]

Parti del comando SELECT:

predicate: uno dei seguenti: ALL, DISTINCT, DISTINCTROW, o TOP (vedremo più avanti i dettagli).
Si usa il predicate per restringere il numero dei records restituiti; se omesso il default è ALL.

(*): Indica che sono scelti tutti i campi della Table (o delle Tables).
table Il nome della Table contenente i campi dalla quale vengono scelti i records.
field1, field2 Il nome dei campi contenenti i dati cercati. Se si includono più campi vengono restituiti nell'ordine elencato.
alias1, alias2 I nomi da usare come testata delle colonne invece dei nomi di colonna originali della Table.

Da notare che qualora i campi provengano da più Tables in caso di sinonimi occorre utilizzare la sintassi nometable.nomefield per determinare un campo in modo univoco.

» clausola FROM
tableexpression: una espressione che identifica una o più Tables contenenti i dati da cercare; l'espressione può essere il nome di una Table, il nome di una Query salvata o il risultato di una INNER JOIN, LEFT JOIN, o RIGHT JOIN (vedremo più avanti i dettagli).
externaldatabase: il nome del Database contenente le Tables in tableexpression se non è il Database corrente.

» clausola WHERE
Indica il criterio di scelta: l'elemento base è nomefield operatore di confronto valore|nomefield; possono essere concatenati più elementi base tramite gli operatori logici (And Or).
Esempio: WHERE NomeImpiegato="Paolo" And (ImportoOrdini>10000000 Or NumeroOrdini>100)
Note:
nell'eseguire questa operazione il motore database Microsoft Jet cerca la Table (o Tables) specificata, estrae le colonne (=campi) scelte, individua le righe (=record) che soddisfano il criterio ed ordina o raggruppa le righe risultanti nell'ordine specificato.
Il comando SELECT non modifica i dati del database.
La sintassi minima è:

SELECT fields FROM table

Usando un aterisco (*) si scelgono tutti i campi di una Table; l'esempio seguente: SELECT * FROM Employees è equivalente ad usare come RecordSet Employees.

» Clausola GROUP BY
Combina i records con valori identici del campo specificato in un singolo record. Un valore riepilogativo è creato se nel comando SELECT viene inclusa una funzione SQL di aggregazione, quale Sum o Count.
Sintassi:

[GROUP BY groupfieldlist]
groupfieldlist Il nome di fino a 10 campi usati per raggruppare i records; l'ordine dei campi in groupfieldlist determina il livello di grouping da quello più alto a quello più basso
.
Note:
I valori riepilogativi vengono omessi se non è indicata una funzione SQL di aggregazione nel comando SELECT.
Valori Null nei campi di GROUP BY vengono raggruppati e non saltati; tuttavia i valori Null non vengono considerati da alcuna funzione SQL di aggregazione.
Usare la clausola WHERE per escludere i records che non si vuole raggruppare, usare la calusola HAVING per filtrare i records dopo che sono stati raggruppati.
Non possono essere usati come campi GROUP BY né campi Memo né campi OLE Object; possono invece essere usati tutti gli altri campi di qualsiasi Table indicata nella clausola FROM, anche se detti campi non sono inclusi nella lista della SELECT purché sia inclusa almeno una funzione SQL di aggregazione.

» Clausola HAVING
Specifica quali records raggruppati vengono restituiti da un comando SELECT con clausola GROUP BY.
Sintassi:

SELECT .........
FROM ...........
WHERE ..........
GROUP BY groupfieldlist
HAVING groupcriteria

groupfieldlist: già esaminato in precedenza.
groupcriteria: un'espressione che determina quali records raggruppati restituire; possono essere usate fino a 40 espressioni collegate dagli operatori And e Or.
Esempio:

SELECT CategoryID, Sum(UnitsInStock)
FROM Products
GROUP BY CategoryID
HAVING Sum(UnitsInStock) > 100

Dalla Table Products per ogni CategoryID presente otteniamo un record con 2 campi (CategoryID e UnitsInStock) contenente nel 2° la somma dei valori di tutti i records avente uguale CategoryID solo se detta somma è maggiore di 100.

» Clausola ORDER BY
Ordina i records risultato di una query secondo uno o più campi specificati in sequenza ascendente o discendente.

Sintassi:

SELECT .........
FROM ...........
[WHERE ..........]
[GROUP BY ...... [HAVING ....]]
[ORDER BY field1 [ASC|DESC][, field2 [ASC|DESC]][, ...]]]

field1, field2, I nomi dei campi di sort.
Note:
l'ordine di default è ascendente; i due esempi seguenti sono equivalenti:

SELECT LastName, FirstName
FROM Employees
ORDER BY LastName

SELECT LastName, FirstName
FROM Employees
ORDER BY LastName ASC

Per ordinare in senso discendente (Z ad A, 9 a 0) aggiungere DESC dopo il nome del campo; l'esempio seguente ordina per stipendi decrescenti:

SELECT LastName, FirstName, Salary
FROM Employees
ORDER BY Salary DESC, LastName

Non è possibile specificare nella clausola ORDER BY né campi Memo né campi OLE Object; i records vengono ordinati sul 1° campo e quelli con ugual valore vengono quindi ordinati sul 2° e così via.

Dichiarazione WITH OWNERACCESS OPTION

In un ambiente multiutente con sicurezze a livello di workgroup, utilizzare questa dichiarazione con una query per dare all'utente della query le stesse abilitazioni del proprietario della query.

L'esempio seguente abilita l'utente a vedere dati salariali (anche se non è abilitato ad accedere alla Table Stipendi) purché il proprietario della query abbia tale abilitazione:

SELECT Cognome, Nome, Salario
FROM Stipendi
ORDER BY Cognome
WITH OWNERACCESS OPTION

Questa opzione richiede che abbiate accesso al file System.mdw associato al Database; è utile solo in implementazioni multiutente protette.

» Predicati ALL, DISTINCT, DISTINCTROW, TOP
Specificano i records restituiti dalla query SQL.
Sintassi.

SELECT [ALL | DISTINCT | DISTINCTROW | [TOP n [PERCENT]]]
FROM table [ altre clausole .......]

ALL = tutti; assunto di default: il motore Microsoft Jet sceglie tutti i records che soddisfano le condizioni nel comando SQL.
DISTINCT Omette i records contenenti dati duplicati nei campi indicati; per esempio più impiegati nella Table Employees possono avere lo stesso LastName.
Se 2 records contengono Smith nel campo LastName il seguente comando SQL ritorna un solo record contenente Smith:

SELECT DISTINCT LastName FROM Employees

L'output di una query che usa DISTINCT non è Updatable.
DISTINCTROW: omette i dati basati su records interamente duplicati. Per esempio voi create una query che unisce le Tables Customers e Orders sulla base del campo CustomerID; Customers non contiene CustomerID duplicati, ma Orders può in quanto ogni customer può avere vari orders. Il seguente comando SQL produce una lista delle compagnie che hanno almeno un ordine (anche se senza alcun dettaglio riguardo agli ordini):

SELECT DISTINCTROW CompanyName
FROM Customers INNER JOIN Orders
ON Customers.CustomerID = Orders.CustomerID
ORDER BY CompanyName

DISTINCTROW ha effetto solo si scelgono campi da alcune ma non tutte le Tables usate nella query ed è ignorata se la query include una sola Table o se si scelgono campi da tutte le Tables.
TOP n [PERCENT]: ritorna solo un cero numero dei records che cadono all'inizio o alla fine di una graduatoria specificata da una clausola ORDER BY ; vogliamo i nomi dei migliori 25 studenti diplomati nel 1994:

SELECT TOP 25 FirstName, LastName
FROM Students
WHERE GraduationYear = 1994
ORDER BY GradePointAverage DESC

Se si omette la clausola ORDER BY la query ritorna un insieme arbitrario di 25 records della Table Students che soddisfano la clausola WHERE.
TOP non sceglie tra valori uguali: se il 25° ed il 26° studente hanno la stessa media la query restituisce 26 records.
Se si usa PERCENT viene restituita quella percentuale dei records che soddisfano la query: se invece dei migliori 25 vogliamo il 10% peggiore dei diplomati 1994:

SELECT TOP 10 PERCENT FirstName, LastName
FROM Students
WHERE GraduationYear = 1994
ORDER BY GradePointAverage ASC

ASC e DESC specificano il senso dell'ordinamento (ascending o descending); il valore che segue TOP deve essere un intero senza segno.

Operazioni di JOIN, LEFT JOIN, RIGHT JOIN in SQL

» INNER JOIN
Combina records da due tables quando hanno valori corrispondenti in un campo comune.
Sintassi:

FROM table1 INNER JOIN table2 ON table1.field1 compareop table2.field2

table1, table2: inomi delle Tables dalle quali combinare i records.
field1, field2: inomi dei campi oggetto della join. Devono essere dello stesso data type e contenere la stessa specie di dati, ma non è necessario che abbiano lo stesso nome.
compareop: un' operatore relazionale: "=," "<," ">," "<=," ">=," o "<>."
Note:
se si usano come campi di join campi Memo o OLE Object si causa un errore.
Tra due campi numerici è possibile la join solo se sono dello stesso tipo: per esempio AutoNumber (Contatore) e Long sono dello stesso tipo; Single e Double non sono dello stesso tipo e si causa un errore.
La INNER JOIN combina i records da due Tables quando hanno valori corrispondenti in un campo comune ad entrambe le Tables.
Potete usare INNER JOIN con le Tables Departments e Employees per ottenere tutti gli impiegati di ogni dipartimento. Se invece volete tutti i dipartimenti (anche se non hanno alcun impiegato assegnato) o tutti gli impiegati (anche se qualcuno non è assegnato ad alcun dipartimento), dovete usare una operazione LEFT JOIN o RIGHT JOIN per creare una "outer join".
L'esempio mostra la join delle Tables Categories and Products tramite il campo CategoryID:

SELECT CategoryName, ProductName
FROM Categories INNER JOIN Products
ON Categories.CategoryID = Products.CategoryID

CategoryID è il campo di join, ma non è incluso nell'output della query non essendo incluso nella fields list della SELECT; per includerlo aggiungere il nome del campo, ovvero Categories.CategoryID.
Si possono collegare più clausole ON in una JOIN usando la seguente sintassi:

SELECT fields
FROM table1 INNER JOIN table2
ON table1.field1 compopr table2.field1 AND
ON table1.field2 compopr table2.field2) OR
ON table1.field3 compopr table2.field3)]

Si possono nidificare le operazioni di JOIN usando la seguente sintassi:

SELECT fields
FROM table1 INNER JOIN
(table2 INNER JOIN [( ]table3
[INNER JOIN [( ]tablex [INNER JOIN ...)]
ON table3.field3 compopr tablex.fieldx)]
ON table2.field2 compopr table3.field3)
ON table1.field1 compopr table2.field2

Una LEFT JOIN o una RIGHT JOIN possono essere nidificate dentro una INNER JOIN, ma una INNER JOIN non può essere nidificata entro una LEFT JOIN o una RIGHT JOIN.

» LEFT JOIN, RIGHT JOIN
Sintassi:

FROM table1 [ LEFT | RIGHT ] JOIN table2
ON table1.field1 compopr table2.field2

La sintassi è identica a quella della INNER JOIN.
Note:
se si usano come campi di join campi Memo o OLE Object si causa un errore.
L'operatore LEFT JOIN crea una join esterna sinistra, ovvero include tutti i records della prima (left) Table anche se non c'è corrispondenza con i records nella seconda (right) Table.
L'operatore RIGHT JOIN crea una join esterna destra, ovvero include tutti i records della seconda (right) Table anche se non c'è corrispondenza con i records nella prima (left) Table.
Per esempio useremo LEFT JOIN con le Tables Departments (left) e Employees (right) per ottenere tutti i dipartimenti, inclusi quelli che non hanno impiegati assegnati; per ottenere invece tutti gli impiegati, inclusi quelli non assegnati ad un dipartimento, useremo RIGHT JOIN.
LEFT JOIN o RIGHT JOIN possono essere nidificate all'interno di INNER JOIN, ma INNER JOIN non può essere nidificata entro LEFT JOIN o RIGHT JOIN; per la sintassi di nidificazione vale quanto detto per INNER JOIN, così come per le clausole ON multiple ed i campi Memo o OLE Object.

Altri comandi SQL

» SELECT .... INTO Statement
Query di creazione di una Table.
Sintassi:

SELECT field1[, field2[, ...]] INTO newtable [IN externaldatabase]
FROM source

Crea una nuova Table, eventualmente in un Db esterno, avente i campi specificati nella fields list; non può essere utilizzata per aggiungere records ad una Table esistente.

» DELETE Statement
Query di cancellazione dei records di una Table che soddisfano un determinato criterio.
Sintassi:

DELETE [table.*]
FROM table
WHERE criteria

DELETE serve per cancellazioni multiple; inoltre se la Table da cui si cancella è posta in una relazione uno-a-molti con altre Tables vengono cancellati anche i records relativi dalle altre Tables.
Per esempio se la Table "Customers" è in relazione uno-a-molti con la Table "Orders" cancellando alcuni clienti da Customers si otterrà anche la cancellazione degli ordini relativi da Orders.

» INSERT INTO Statement
Query di inserimento di uno o più records in una Table (append query).
Sintassi:

(Multiple-record append query):

INSERT INTO target [(field1[, field2[, ...]])] [IN externaldatabase]
SELECT [source.]field1[, field2[, ...]
FROM tableexpression

(Single-record append query):

INSERT INTO target [(field1[, field2[, ...]])]
VALUES (value1[, value2[, ...])

Qualora la Table di destinazione abbia un campo Contatore (Autonumber) non inserire tale campo nella fields list; la clausola FORM può anche contenere JOIN di più Tables.

» UPDATE, DELETE e INSERT Statements
Le applicazioni SQL-based effettuano gli aggiornamenti delle Tables con l'esecuzione dei comandi UPDATE, DELETE ed INSERT. Questi comandi fanno parte del "Minimum SQL grammar conformance level" e devono essere supportati da tutti i drivers e da tutti i Database.
Sintassi:

UPDATE table-name
SET column-identifier = {expression | NULL}
[, column-identifier = {expression | NULL}]...
[WHERE search-condition]

DELETE FROM table-name [WHERE search-condition]

INSERT INTO table-name [(column-identifier [, column-identifier]...)]
{query-specification | VALUES (insert-value [, insert-value]...)}

Questi comandi sono riportati a puro titolo esemplificativo non essendo utilizzabili nella programmazione Visual Basic dove invece si ricorre in genere a Metodi applicati agli Oggetti.

Approfondimenti

» "Interactive/On-line SQL Tutorial" di F. Torres
» "SQL Index"
» "Interactive SQL" di Jean Anderson
» "Database glossary"
» "Starting a Career in Databases"
» "A pratical SQL Tutorial"