Codice dei programmi nella directory:

///File: SQL-DML.htm
<!DOCTYPE HTML PUBLIC "ISO/IEC 15445:2000//DTD HTML//EN"> <html lang="it"><head> <meta http-equiv="Content-Type" content="text/html;charset=us-ascii"> <meta name="Generator" content="Alml"> <meta name="Description" content="GNU/Linux e altro software libero"> <meta name="Keywords" content="Linux, GNU/Linux, Unix, software, software libero, free software"> <meta name="Author" content="Daniele Giacomini &nbsp;&nbsp; &lt;appunti2&#8201;(ad)&#8201;gmail&#183;com&gt;"> <meta name="Date" content="2008"> <meta name="Resource-type" content="Document" lang="en"> <meta name="Revisit-after" content="15 days" lang="en"> <meta name="Robots" content="ALL"><title>a2 --- Linguaggio SQL: DML</title> <style type="text/css"> <!-- BODY { background-color: rgb(255, 255, 255); } H1 { text-align: right; color: rgb(230, 100, 180); /* */ } SAMP { quotes: "'" "'"; font-weight: bold; } SAMP:before { content: open-quote; } SAMP:after { content: close-quote; } CODE.file { quotes: "'" "'"; } CODE.file:before { content: open-quote; } CODE.file:after { content: close-quote; } P.syntax { width: auto; text-align: left } P.caption { text-align: left; font-style: italic; width: 100%; background-color: rgb(211, 211, 211); /* light gray */ } P.command { text-align: left; width: auto; /* width: 100%; */ border-style: none; background-color: rgb(255, 170, 255); /* light magenta */ } EM.promptinfo { text-align: left; width: auto; border-style: none; background-color: rgb(0, 255, 0); /* green */ font-size: 80%; } P.fullpagepicture { text-align: center; } P { /* text-align: justify */ text-align: left } P.validator { border-style: none; } P.testtime { text-align: right; } P.testsend { text-align: right; } DIV.listing { width: auto; background-color: rgb(173, 216, 230); /* light blue */ } DIV.object { width: auto; } TABLE.frame { width: 100%; border-color: black; border-style: solid; background-color: yellow; border-width: thin; } TABLE.pre { /* width: 100%; */ width: auto; border-color: black; border-style: solid; background-color: rgb(211, 211, 211); /* light gray */ border-width: thin; } TABLE.syntax { /* width: 100%; */ width: auto; border-color: black; border-style: solid; background-color: rgb(170, 255, 255); /* light cyan */ border-width: thin; } TABLE.figurewrapper { width: 100%; border-style: none; } TABLE.figure { width: 100%; border-color: black; border-style: solid; background-color: rgb(211, 211, 211); /* light gray */ border-width: thin; } TABLE.listing { /* width: 100%; */ width: auto; border-color: black; border-style: solid; border-width: thin; } TABLE.object { /* width: 100%; */ width: auto; border-color: green; border-style: solid; border-width: thin; } TABLE.table { width: 100%; border-color: black; border-style: solid; border-width: thin; background-color: rgb(190, 255, 190); /* light green */ } THEAD.border { background-color: rgb(224, 255, 255); /* light cyan */ border-color: black; border-style: solid; border-width: thin; } THEAD.noborder { background-color: rgb(224, 255, 255); /* light cyan */ border-color: black; border-style: solid; border-width: thin; } TBODY.border { border-color: black; border-style: solid; border-width: thin; } TBODY.noborder { border-style: none; } TD.border { border-color: black; border-style: solid; border-width: thin; } TR.noborder { border-style: none; } TABLE.testinfo { width: 100%; border-color: black; border-style: solid; border-width: thin; } TBODY.testinfo { border-style: none; } COL.testinfolabel { border-style: none; width: 300px; } COL.testinfofield { border-style: none; width: 400px; } TD.testinfo { border-style: none; } STRONG.syn { font-size: 120%; } STRONG.newline { font-size: 162%; } SPAN.big { font-size: 120%; } SPAN.small { font-size: 80%; } SPAN.visible_label { font-size: 75%; font-style: italic; font-weight: bold; color: blue; border-color: green; border-style: solid; border-width: thin; } SPAN.command { background-color: rgb(255, 170, 255); /* light magenta */ } SPAN.posix { text-decoration: underline; } HR.object { color: green; } A:hover { color: #fff; background: #00c; } --> </style> <link rel="Start" title="Start" href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2.htm"> <link rel="Prev" title="Previous" href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2860.htm"> <link rel="Next" title="Next" href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2862.htm"></head><body> <p> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2862.htm">[successivo]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2860.htm">[precedente]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2.htm">[inizio]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a21088.htm">[fine]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a21.htm">[indice generale]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a22.htm">[indice ridotto]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a21088.htm">[indice analitico]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2855.htm">[volume]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2856.htm">[parte]</a> </p> <hr> <h1>Capitolo 692. &nbsp; <a name="almltitle6084"></a><a name="almlanchor16155"></a> Linguaggio <a name="almlindex19129"></a>SQL: DML <a name="almlindex19130"></a> <a name="almlindex19131"></a> <a name="almlindex19132"></a> </h1> <p>DML, ovvero <em>Data manipulation language</em>, &#232; il linguaggio usato per inserire, modificare e accedere ai dati. In questo capitolo viene trattato il linguaggio <a name="almlindex19133"></a>SQL per ci&#242; che riguarda specificatamente l'inserimento, la lettura e la modifica del contenuto delle relazioni.</p> <h2>692.1 &nbsp; <a name="almltitle6085"></a><a name="almlanchor16156"></a> Inserimento, eliminazione e modifica dei dati </h2> <p>L'inserimento, l'eliminazione e la modifica dei dati di una relazione &#232; un'operazione che interviene sempre a livello delle tuple. Infatti, come gi&#224; definito, la tupla &#232; l'elemento che costituisce l'unit&#224; di dati pi&#249; piccola che pu&#242; essere inserita o cancellata da una relazione.</p> <h3>692.1.1 &nbsp; <a name="almltitle6086"></a><a name="almlanchor16157"></a> Inserimento di tuple <a name="almlindex19134"></a> </h3> <p>L'inserimento di una nuova tupla all'interno di una relazione viene eseguito attraverso l'istruzione <samp>INSERT</samp>. Dal momento che nel modello di <a name="almlindex19135"></a>SQL gli attributi sono ordinati, &#232; sufficiente indicare ordinatamente l'elenco dei valori della tupla da inserire, come mostra la sintassi seguente:</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>INSERT INTO <var>nome_relazione</var> VALUES (<var>espressione_1</var><strong class="syn">[</strong>,...<var>espressione_n</var><strong class="syn">]</strong>) </pre> </td></tr></tbody> </table> <p>Per esempio, l'inserimento di una tupla nella relazione <samp>Indirizzi</samp> gi&#224; mostrata in precedenza, potrebbe avvenire nel modo seguente:</p> <table summary="" id="almlanchor16158"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>INSERT INTO Indirizzi VALUES ( 01, 'Pallino', 'Pinco', 'Via Biglie 1', '0222,222222' ) </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>Se i valori inseriti sono meno del numero degli attributi della relazione, i valori mancanti, in coda, ottengono quanto stabilito come valore predefinito, o <samp>NULL</samp> in sua mancanza (sempre che ci&#242; sia concesso dai vincoli della relazione).</p> <p>L'inserimento dei dati pu&#242; avvenire in modo pi&#249; chiaro e sicuro elencando prima i nomi degli attributi, in modo da evitare di dipendere dalla sequenza degli attributi memorizzata nella relazione. La sintassi seguente mostra il modo di ottenere questo.</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>INSERT INTO <var>nome_relazione</var> (<var>attributo_1</var><strong class="syn">[</strong>,...<var>attributo_n</var>])<strong class="syn">]</strong> VALUES (<var>espressione_1</var><strong class="syn">[</strong>,...<var>espressione_n</var><strong class="syn">]</strong>) </pre> </td></tr></tbody> </table> <p>L'esempio gi&#224; visto potrebbe essere tradotto nel modo seguente, pi&#249; prolisso, ma anche pi&#249; chiaro:</p> <table summary="" id="almlanchor16159"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>INSERT INTO Indirizzi ( Codice, Cognome, Nome, Indirizzo, Telefono ) VALUES ( 01, 'Pallino', 'Pinco', 'Via Biglie 1', '0222,222222' ) </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>Questo modo esplicito di fare riferimento agli attributi garantisce anche che eventuali modifiche di lieve entit&#224; nella struttura della relazione non debbano necessariamente riflettersi nei programmi. L'esempio seguente mostra l'inserimento di alcuni degli attributi della tupla, lasciando che gli altri ottengano l'assegnamento di un valore predefinito.</p> <table summary="" id="almlanchor16160"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>INSERT INTO Indirizzi ( Codice, Cognome, Nome, Telefono ) VALUES ( 01, 'Pinco', 'Pallino', '0222,222222' ) </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <h3>692.1.2 &nbsp; <a name="almltitle6087"></a><a name="almlanchor16161"></a> Aggiornamento delle tuple <a name="almlindex19136"></a> </h3> <p>La modifica delle tuple pu&#242; avvenire attraverso una scansione della relazione, dalla prima all'ultima tupla, eventualmente controllando la modifica in base all'avverarsi di determinate condizioni. La sintassi per ottenere questo risultato, leggermente semplificata, &#232; la seguente:</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>UPDATE <var>relazione</var> SET <var>attributo_1</var>=<var>espressione_1</var><strong class="syn">[</strong>,...<var>attributo_n</var>=<var>espressione_n</var><strong class="syn">]</strong> <strong class="syn">[</strong>WHERE <var>condizione</var><strong class="syn">]</strong> </pre> </td></tr></tbody> </table> <p>L'istruzione <samp>UPDATE</samp> esegue tutte le sostituzioni indicate dalle coppie <var>attributo</var>=<var>espressione</var>, per tutte le tuple in cui la condizione posta dopo la parola chiave <samp>WHERE</samp> si avvera. Se tale condizione manca, l'effetto delle modifiche si riflette su tutte le tuple della relazione.</p> <p>L'esempio seguente aggiunge un attributo alla relazione degli indirizzi, per contenere il nome del comune di residenza; successivamente viene inserito il nome del comune &#171;Sferopoli&#187; in base al prefisso telefonico.</p> <table summary="" id="almlanchor16162"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>ALTER TABLE Indirizzi ADD COLUMN Comune char(30) </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <table summary="" id="almlanchor16163"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>UPDATE Indirizzi SET Comune='Sferopoli' WHERE Telefono &gt;= '022' AND Telefono &lt; '023' </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>Eventualmente, al posto dell'espressione si pu&#242; indicare la parola chiave <samp>DEFAULT</samp> che fa in modo di assegnare il valore predefinito per quel attributo.</p> <h3>692.1.3 &nbsp; <a name="almltitle6088"></a><a name="almlanchor16164"></a> Eliminazione di tuple <a name="almlindex19137"></a> </h3> <p>La cancellazione di tuple da una relazione &#232; un'operazione molto semplice. Richiede solo l'indicazione del nome della relazione e la condizione in base alla quale le tuple devono essere cancellate.</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>DELETE FROM <var>relazione</var> <strong class="syn">[</strong>WHERE <var>condizione</var><strong class="syn">]</strong> </pre> </td></tr></tbody> </table> <table class="frame" summary=""> <tbody><tr><td> <p>Se la condizione non viene indicata, si cancellano tutte le tuple!</p> </td></tr></tbody> </table> <h2>692.2 &nbsp; <a name="almltitle6089"></a><a name="almlanchor16165"></a> Interrogazioni di relazioni </h2> <p>L'interrogazione di una relazione &#232; l'operazione con cui si ottengono i dati contenuti al suo interno, in base a dei criteri di filtro determinati. L'interrogazione consente anche di combinare assieme dati provenienti da relazioni differenti, in base a dei &#171;collegamenti&#187; che possono intercorrere tra queste.</p> <h3>692.2.1 &nbsp; <a name="almltitle6090"></a><a name="almlanchor16166"></a> Interrogazioni elementari <a name="almlindex19138"></a> </h3> <p>La forma pi&#249; semplice di esprimere la sintassi necessaria a interrogare <strong>una</strong> sola relazione &#232; quella espressa dallo schema seguente:</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>SELECT <var>espress_col_1</var><strong class="syn">[</strong>,...<var>espress_col_n</var><strong class="syn">]</strong> FROM <var>relazione</var> <strong class="syn">[</strong>WHERE <var>condizione</var><strong class="syn">]</strong> </pre> </td></tr></tbody> </table> <p>In questo modo &#232; possibile definire gli attributi che si intendono utilizzare per il risultato, mentre le tuple si specificano, eventualmente, con la condizione posta dopo la parola chiave <samp>WHERE</samp>. L'esempio seguente mostra la proiezione degli attributi del cognome e nome della relazione di indirizzi gi&#224; vista negli esempi delle altre sezioni, senza porre limiti alle tuple.</p> <table summary="" id="almlanchor16167"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>SELECT Cognome, Nome FROM Indirizzi </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>Quando si vuole ottenere una selezione composta dagli stessi attributi della relazione originale, nel suo stesso ordine, si pu&#242; utilizzare un carattere jolly particolare, l'asterisco (<samp>*</samp>). Questo rappresenta l'elenco di tutti gli attributi della relazione indicata.</p> <table summary="" id="almlanchor16168"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>SELECT * FROM Indirizzi </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>&#200; bene osservare che gli attributi si esprimono attraverso un'espressione, questo significa che gli attributi a cui si fa riferimento sono quelle del risultato finale, cio&#232; della relazione che viene restituita come selezione o proiezione della relazione originale. L'esempio seguente emette un solo attributo contenente un ipotetico prezzo scontato del 10&nbsp;%, in pratica viene moltiplicato il valore di un attributo contenente il prezzo per 0,90, in modo da ottenerne il 90&nbsp;% (100&nbsp;% meno lo sconto).</p> <table summary="" id="almlanchor16169"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>SELECT Prezzo * 0.90 FROM Listino </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>In questo senso si pu&#242; comprendere l'utilit&#224; di assegnare esplicitamente un nome agli attributi del risultato finale, come indicato dalla sintassi seguente:</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>SELECT <var>espress_col_1</var> AS <var>nome_col_1</var>]<strong class="syn">[</strong>,...<var>espress_col_n</var> AS <var>nome_col_n</var><strong class="syn">]</strong> FROM <var>relazione</var> <strong class="syn">[</strong>WHERE <var>condizione</var><strong class="syn">]</strong> </pre> </td></tr></tbody> </table> <p>In questo modo, l'esempio precedente pu&#242; essere trasformato come segue, dando un nome all'attributo generato e chiarendone cos&#236; il contenuto.</p> <table summary="" id="almlanchor16170"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>SELECT Prezzo * 0.90 AS Prezzo_Scontato FROM Listino </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>Finora &#232; stata volutamente ignorata la condizione che controlla le tuple da selezionare. Anche se potrebbe essere evidente, &#232; bene chiarire che la condizione posta dopo la parola chiave <samp>WHERE</samp> pu&#242; fare riferimento solo ai dati originali della relazione da cui si attingono. Quindi, non &#232; valida una condizione che utilizza un riferimento a un nome che appare dopo la parola chiave <samp>AS</samp> abbinata alle espressioni degli attributi.</p> <p>Per qualche motivo che viene chiarito in seguito, pu&#242; essere conveniente associare un alias alla relazione da cui estrarre i dati. Anche in questo caso si utilizza la parola chiave <samp>AS</samp>, come indicato dalla sintassi seguente:</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>SELECT <var>specificazione_dell'attributo_1</var><strong class="syn">[</strong>,...<var>specificazione_dell'attributo_n</var><strong class="syn">]</strong> FROM <var>relazione</var> AS <var>alias</var> <strong class="syn">[</strong>WHERE <var>condizione</var><strong class="syn">]</strong> </pre> </td></tr></tbody> </table> <p>Quando si vuole fare riferimento al nome di un attributo, se per qualche motivo questo nome dovesse risultare ambiguo, si pu&#242; aggiungere anteriormente il nome della relazione a cui appartiene, separandolo attraverso l'operatore punto (<samp>.</samp>). L'esempio seguente &#232; la proiezione dei cognomi e dei nomi della solita relazione degli indirizzi. In questo caso, le espressioni degli attributi rappresentano solo gli attributi corrispondenti della relazione originaria, con l'aggiunta dell'indicazione esplicita del nome della relazione stessa.</p> <table summary="" id="almlanchor16171"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>SELECT Indirizzi.Cognome, Indirizzi.Nome FROM Indirizzi </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>A questo punto, se al nome della relazione viene abbinato un alias, si pu&#242; esprimere la stessa cosa indicando il nome dell'alias al posto di quello della relazione, come nell'esempio seguente:</p> <table summary="" id="almlanchor16172"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>SELECT Ind.Cognome, Ind.Nome FROM Indirizzi AS Ind </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <h3>692.2.2 &nbsp; <a name="almltitle6091"></a><a name="almlanchor16173"></a> Interrogazioni ordinate </h3> <p>Per ottenere un elenco ordinato in base a qualche criterio, si utilizza l'istruzione <samp>SELECT</samp> con l'indicazione di un'espressione in base alla quale effettuare l'ordinamento. Questa espressione &#232; preceduta dalle parole chiave <samp>ORDER&nbsp;BY</samp>:</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>SELECT <var>espress_col_1</var><strong class="syn">[</strong>,...<var>espress_col_n</var><strong class="syn">]</strong> FROM <var>relazione</var> <strong class="syn">[</strong>WHERE <var>condizione</var><strong class="syn">]</strong> ORDER BY <var>espressione</var> <strong class="syn">[</strong>ASC<strong class="syn">|</strong>DESC<strong class="syn">]</strong> <strong class="syn">[</strong>,...<strong class="syn">]</strong> </pre> </td></tr></tbody> </table> <p>L'espressione pu&#242; essere il nome di un attributo, oppure un'espressione che genera un risultato da uno o pi&#249; attributi; l'aggiunta eventuale della parola chiave <samp>ASC</samp>, o <samp>DESC</samp>, permette di specificare un ordinamento crescente, o discendente. Come si vede, le espressioni di ordinamento possono essere pi&#249; di una, separate con una virgola.</p> <table summary="" id="almlanchor16174"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>SELECT Cognome, Nome FROM Indirizzi ORDER BY Cognome </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>L'esempio mostra un'applicazione molto semplice del problema, in cui si ottiene un elenco dei soli attributi <samp>Cognome</samp> e <samp>Nome</samp>, della relazione <samp>Indirizzi</samp>, ordinato per <samp>Cognome</samp>.</p> <table summary="" id="almlanchor16175"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>SELECT Cognome, Nome FROM Indirizzi ORDER BY Cognome, Nome </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>Questo esempio, aggiunge l'indicazione del nome nella chiave di ordinamento, in modo che in presenza di cognomi uguali, la scelta venga fatta in base al nome.</p> <table summary="" id="almlanchor16176"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>SELECT Cognome, Nome FROM Indirizzi ORDER BY TRIM( Cognome ), TRIM( Nome ) </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>Questo ultimo esempio mostra l'utilizzo di due espressioni come chiave di ordinamento.&nbsp;Per la precisione, la funzione <samp>TRIM()</samp>, usata in questo modo, serve a eliminare gli spazi iniziali e finali superflui. In questo modo, se i nomi e i cognomi sono stati inseriti con degli spazi iniziali, questi non vanno a influire sull'ordinamento.</p> <h3>692.2.3 &nbsp; <a name="almltitle6092"></a><a name="almlanchor16177"></a> Interrogazioni simultanee di pi&#249; relazioni </h3> <p>Se dopo la parola chiave <samp>FROM</samp> si indicano pi&#249; relazioni (ci&#242; vale anche se si indica pi&#249; volte la stessa relazione), si intende fare riferimento a una relazione generata dal prodotto di queste. Se per esempio si vogliono abbinare due relazioni, una di tre tuple con due attributi e un'altra di due tuple con due attributi, quello che si ottiene &#232; una relazione con quattro attributi composta da sei tuple. Infatti, ogni tupla della prima relazione risulta abbinata con ogni tupla della seconda.</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>SELECT <var>specificazione_dell'attributo_1</var><strong class="syn">[</strong>,...<var>specificazione_dell'attributo_n</var><strong class="syn">]</strong> FROM <var>specificazione_della_relazione_1</var><strong class="syn">[</strong>,...<var>specificazione_della_relazione_n</var><strong class="syn">]</strong> <strong class="syn">[</strong>WHERE <var>condizione</var><strong class="syn">]</strong> </pre> </td></tr></tbody> </table> <p>Viene proposto un esempio banalizzato, con il quale poi si vuole eseguire un'elaborazione (figura <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2861.htm#almlanchor16178">692.15</a>).</p> <table summary="" id="almlanchor16178"> <tbody><tr><td> <p class="caption"> Figura <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2861.htm#almlanchor16178">692.15</a>. Relazioni <samp>Articoli</samp> e <samp>Movimenti</samp> di una gestione del magazzino ipotetica. </p> <div class="object"> <table class="object" summary=""> <tbody><tr><td> <p class="fullpagepicture"> <img src="SQL-DML_files/1677.jpg" alt="relazione" title="relazione_19.jpg"> <img src="SQL-DML_files/1678.jpg" alt="relazione" title="relazione_20.jpg"> </p> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>Da questa situazione si vuole ottenere la <a name="almlindex19139"></a>congiunzione della relazione <samp>Movimenti</samp> con tutte le informazioni corrispondenti della relazione <samp>Articoli</samp>, basando il riferimento sull'attributo <samp>Codice</samp>. In pratica si vuole ottenere la relazione della figura <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2861.htm#almlanchor16179">692.16</a>.</p> <table summary="" id="almlanchor16179"> <tbody><tr><td> <p class="caption"> Tabella <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2861.htm#almlanchor16179">692.16</a>. Risultato del <a name="almlindex19140"></a>join che si intende ottenere tra la relazione <samp>Movimenti</samp> e la relazione <samp>Articoli</samp>. </p> <div class="object"> <table class="object" summary=""> <tbody><tr><td> <p class="fullpagepicture"> <img src="SQL-DML_files/1679.jpg" alt="relazione" title="relazione_21.jpg"> </p> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>Considerato che da un'istruzione <samp>SELECT</samp> contenente il riferimento a pi&#249; relazioni si genera il prodotto tra queste, si pone poi il problema di eseguire una proiezione degli attributi desiderati e, soprattutto, di selezionare le tuple. In questo caso, la selezione deve essere basata sulla corrispondenza tra l'attributo <samp>Codice</samp> della prima relazione, con lo stesso attributo della seconda. Dovendo fare riferimento a due attributi di relazioni differenti, aventi per&#242; lo stesso nome, diviene indispensabile indicare i nomi degli attributi prefissandoli con i nomi delle relazioni rispettive.</p> <table summary="" id="almlanchor16180"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>SELECT Movimenti.Codice, Movimenti.Data, Movimenti.Carico, Movimenti.Scarico, Articoli.Descrizione FROM Movimenti, Articoli WHERE Movimenti.Codice = Articoli.Codice; </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>L'interrogazione simultanea di pi&#249; relazioni si presta anche per elaborazioni della stessa relazione pi&#249; volte. In tal caso, diventa obbligatorio l'uso degli alias. Si osservi il caso seguente:</p> <table summary="" id="almlanchor16181"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>SELECT Ind1.Cognome, Ind1.Nome FROM Indirizzi AS Ind1, Indirizzi AS Ind2 WHERE Ind1.Cognome = Ind2.Cognome AND Ind1.Nome &lt;&gt; Ind2.Nome </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>Il senso di questa interrogazione, che utilizza la stessa relazione degli indirizzi per due volte con due alias differenti, &#232; quello di ottenere l'elenco delle persone che hanno lo stesso cognome, avendo per&#242; un nome differente.</p> <p>Esiste anche un'altra situazione in cui si ottiene l'interrogazione simultanea di pi&#249; relazioni: l'<strong><em>unione</em></strong>. Si tratta semplicemente di attaccare il risultato di un'interrogazione su una relazione con quello di un'altra relazione, quando gli attributi finali appartengono allo stesso tipo di dati.</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>SELECT <var>specificazione_dell'attributo_1</var><strong class="syn">[</strong>,...<var>specificazione_dell'attributo_n</var><strong class="syn">]</strong> FROM <var>specificazione_della_relazione_1</var><strong class="syn">[</strong>,...<var>specificazione_della_relazione_n</var><strong class="syn">]</strong> <strong class="syn">[</strong>WHERE <var>condizione</var><strong class="syn">]</strong> UNION SELECT <var>specificazione_dell'attributo_1</var><strong class="syn">[</strong>,...<var>specificazione_dell'attributo_n</var><strong class="syn">]</strong> FROM <var>specificazione_della_relazione_1</var><strong class="syn">[</strong>,...<var>specificazione_della_relazione_n</var><strong class="syn">]</strong> <strong class="syn">[</strong>WHERE <var>condizione</var><strong class="syn">]</strong> </pre> </td></tr></tbody> </table> <p>Lo schema sintattico dovrebbe essere abbastanza esplicito: si uniscono due istruzioni <samp>SELECT</samp> in un risultato unico, attraverso la parola chiave <samp>UNION</samp>.</p> <h3>692.2.4 &nbsp; <a name="almltitle6093"></a><a name="almlanchor16182"></a> Condizioni </h3> <p>La condizione che esprime la selezione delle tuple pu&#242; essere composta come si vuole, purch&#233; il risultato sia di tipo logico e i dati a cui si fa riferimento provengano dalle relazioni di partenza. Quindi si possono usare anche altri operatori di confronto, funzioni e operatori booleani.</p> <table class="frame" summary=""> <tbody><tr><td> <p>&#200; bene ricordare che il valore indefinito, rappresentato da <samp>NULL</samp>, &#232; diverso da qualunque altro valore, compreso un altro valore indefinito. Per verificare che un valore sia o non sia indefinito, si deve usare l'operatore <samp>IS NULL</samp> oppure <samp>IS NOT NULL</samp>.</p> </td></tr></tbody> </table> <h3>692.2.5 &nbsp; <a name="almltitle6094"></a><a name="almlanchor16183"></a> Aggregazioni </h3> <p>L'aggregazione &#232; una forma di interrogazione attraverso cui si ottengono risultati riepilogativi del contenuto di una relazione, in forma di relazione contenente una sola tupla. Per questo si utilizzano delle funzioni speciali al posto dell'espressione che esprime gli attributi del risultato. Queste funzioni restituiscono un solo valore e come tali concorrono a creare un'unica tupla. Le funzioni di aggregazione sono: <samp>COUNT()</samp>, <samp>SUM()</samp>, <samp>MAX()</samp>, <samp>MIN()</samp>, <samp>AVG()</samp>. Per intendere il problema, si osservi l'esempio seguente:</p> <table summary="" id="almlanchor16184"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>SELECT COUNT(*) FROM Movimenti WHERE ... </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>In questo caso, quello che si ottiene &#232; solo il numero di tuple della relazione <samp>Movimenti</samp> che soddisfano la condizione posta dopo la parola chiave <samp>WHERE</samp> (qui non &#232; stata indicata). L'asterisco posto come parametro della funzione <samp>COUNT()</samp> rappresenta effettivamente l'elenco di tutti i nomi degli attributi della relazione <samp>Movimenti</samp>.</p> <p>Quando si utilizzano funzioni di questo tipo, occorre considerare che l'elaborazione si riferisce alla relazione virtuale generata dopo la selezione posta da <samp>WHERE</samp>.</p> <p>La funzione <samp>COUNT()</samp> pu&#242; essere descritta attraverso la sintassi seguente:</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>COUNT( * ) </pre> </td></tr></tbody> </table> <table class="syntax" summary=""> <tbody><tr><td> <pre>COUNT( <strong class="syn">[</strong>DISTINCT<strong class="syn">|</strong>ALL<strong class="syn">]</strong> <var>lista_attributi</var>) </pre> </td></tr></tbody> </table> <p>Utilizzando la forma gi&#224; vista, quella dell'asterisco, si ottiene solo il numero delle tuple della relazione. L'opzione <samp>DISTINCT</samp>, seguita da una lista di nomi di attributi, fa in modo che vengano contate le tuple contenenti valori differenti per quel gruppo di attributi. L'opzione <samp>ALL</samp> &#232; implicita quando non si usa <samp>DISTINCT</samp> e indica semplicemente di contare tutte le tuple.</p> <table class="frame" summary=""> <tbody><tr><td> <p>Il conteggio delle tuple esclude in ogni caso quelle in cui il contenuto di tutti gli attributi selezionati &#232; indefinito (<samp>NULL</samp>).</p> </td></tr></tbody> </table> <p>Le altre funzioni aggreganti non prevedono l'asterisco, perch&#233; fanno riferimento a un'espressione che genera un risultato per ogni tupla ottenuta dalla selezione.</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>SUM( <strong class="syn">[</strong>DISTINCT<strong class="syn">|</strong>ALL<strong class="syn">]</strong> <var>espressione</var>) </pre> </td></tr></tbody> </table> <table class="syntax" summary=""> <tbody><tr><td> <pre>MAX( <strong class="syn">[</strong>DISTINCT<strong class="syn">|</strong>ALL<strong class="syn">]</strong> <var>espressione</var>) </pre> </td></tr></tbody> </table> <table class="syntax" summary=""> <tbody><tr><td> <pre>MIN( <strong class="syn">[</strong>DISTINCT<strong class="syn">|</strong>ALL<strong class="syn">]</strong> <var>espressione</var>) </pre> </td></tr></tbody> </table> <table class="syntax" summary=""> <tbody><tr><td> <pre>AVG( <strong class="syn">[</strong>DISTINCT<strong class="syn">|</strong>ALL<strong class="syn">]</strong> <var>espressione</var>) </pre> </td></tr></tbody> </table> <p>In linea di massima, per tutti questi tipi di funzioni aggreganti, l'espressione deve generare un risultato numerico, sul quale calcolare la sommatoria, <samp>SUM()</samp>, il valore massimo, <samp>MAX()</samp>, il valore minimo, <samp>MIN()</samp>, la media, <samp>AVG()</samp>.</p> <p>L'esempio seguente calcola lo stipendio medio degli impiegati, ottenendo i dati da un'ipotetica relazione <samp>Emolumenti</samp>, limitandosi ad analizzare le tuple riferite a un certo settore.</p> <table summary="" id="almlanchor16185"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>SELECT AVG( Stipendio ) FROM Emolumenti WHERE Settore = 'Amministrazione' </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>L'esempio seguente &#232; una variante in cui si estraggono rispettivamente lo stipendio massimo, medio e minimo.</p> <table summary="" id="almlanchor16186"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>SELECT MAX( Stipendio ), AVG( Stipendio ), MIN( Stipendio ) FROM Emolumenti WHERE Settore = 'Amministrazione' </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>L'esempio seguente &#232; invece volutamente <strong>errato</strong>, perch&#233; si mescolano funzioni aggreganti assieme a espressioni di attributi normali.</p> <table summary="" id="almlanchor16187"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>-- Esempio errato SELECT MAX( Stipendio ), Settore FROM Emolumenti WHERE Settore = 'Amministrazione' </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <h3>692.2.6 &nbsp; <a name="almltitle6095"></a><a name="almlanchor16188"></a> Raggruppamenti </h3> <p>Le aggregazioni possono essere effettuate in riferimento a gruppi di tuple, distinguibili in base al contenuto di uno o pi&#249; attributi. In questo tipo di interrogazione si pu&#242; generare solo una relazione composta da tanti attributi quanti sono quelli presi in considerazione dall'opzione di raggruppamento, assieme ad altre contenenti solo espressioni di aggregazione.</p> <p>Alla sintassi normale gi&#224; vista nelle sezioni precedenti, si aggiunge la clausola <samp>GROUP BY</samp>.</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>SELECT <var>specificazione_dell'attributo_1</var><strong class="syn">[</strong>,...<var>specificazione_dell'attributo_n</var><strong class="syn">]</strong> FROM <var>specificazione_della_relazione_1</var><strong class="syn">[</strong>,...<var>specificazione_della_relazione_n</var><strong class="syn">]</strong> <strong class="syn">[</strong>WHERE <var>condizione</var><strong class="syn">]</strong> GROUP BY <var>attributo_1</var><strong class="syn">[</strong>,...<strong class="syn">]</strong> </pre> </td></tr></tbody> </table> <p>Per comprendere l'effetto di questa sintassi, si deve scomporre idealmente l'operazione di selezione da quella di raggruppamento:</p> <ol> <li> <p>la relazione ottenuta dall'istruzione <samp>SELECT...FROM</samp> viene filtrata dalla condizione <samp>WHERE</samp>;</p> </li> <li> <p>la relazione risultante viene riordinata in modo da raggruppare le tuple in cui i contenuti degli attributi elencati dopo l'opzione <samp>GROUP BY</samp> sono uguali;</p> </li> <li> <p>su questi gruppi di tuple vengono valutate le funzioni di aggregazione.</p> </li> </ol> <table summary="" id="almlanchor16189"> <tbody><tr><td> <p class="caption"> Figura <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2861.htm#almlanchor16189">692.23</a>. Carichi e scarichi in magazzino. </p> <div class="object"> <table class="object" summary=""> <tbody><tr><td> <p class="fullpagepicture"> <img src="SQL-DML_files/1680.jpg" alt="relazione" title="relazione_22.jpg"> </p> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>Si osservi la relazione riportata in figura <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2861.htm#almlanchor16189">692.23</a>, mostra la solita sequenza di carichi e scarichi di magazzino. Si potrebbe porre il problema di conoscere il totale dei carichi e degli scarichi per ogni articolo di magazzino. La richiesta pu&#242; essere espressa con l'istruzione seguente:</p> <table summary="" id="almlanchor16190"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>SELECT Codice, SUM( Carico ), SUM( Scarico ) FROM Movimenti GROUP BY Codice </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>Quello che si ottiene appare nella figura <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2861.htm#almlanchor16191">692.25</a>.</p> <table summary="" id="almlanchor16191"> <tbody><tr><td> <p class="caption"> Figura <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2861.htm#almlanchor16191">692.25</a>. Carichi e scarichi totali. </p> <div class="object"> <table class="object" summary=""> <tbody><tr><td> <p class="fullpagepicture"> <img src="SQL-DML_files/1681.jpg" alt="relazione" title="relazione_23.jpg"> </p> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>Volendo si possono fare i raggruppamenti in modo da avere i totali distinti anche in base al giorno, come nell'istruzione seguente:</p> <table summary="" id="almlanchor16192"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>SELECT Codice, Data, SUM( Carico ), SUM( Scarico ) FROM Movimenti GROUP BY Codice, Data </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>Come gi&#224; affermato, la condizione posta dopo la parola chiave <samp>WHERE</samp> serve a filtrare inizialmente le tuple da considerare nel raggruppamento. Se quello che si vuole &#232; filtrare ulteriormente il risultato di un raggruppamento, occorre usare la clausola <samp>HAVING</samp>.</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>SELECT <var>specificazione_dell'attributo_1</var><strong class="syn">[</strong>,...<var>specificazione_dell'attributo_n</var><strong class="syn">]</strong> FROM <var>specificazione_della_relazione_1</var><strong class="syn">[</strong>,...<var>specificazione_della_relazione_n</var><strong class="syn">]</strong> <strong class="syn">[</strong>WHERE <var>condizione</var><strong class="syn">]</strong> GROUP BY <var>attributo_1</var><strong class="syn">[</strong>,...<strong class="syn">]</strong> HAVING <var>condizione</var> </pre> </td></tr></tbody> </table> <p>L'esempio seguente serve a ottenere il raggruppamento dei carichi e scarichi degli articoli, limitando per&#242; il risultato a quelli per i quali sia stata fatta una quantit&#224; di scarichi consistente (superiore a 1&nbsp;000 unit&#224;).</p> <table summary="" id="almlanchor16193"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>SELECT Codice, SUM( Carico ), SUM( Scarico ) FROM Movimenti GROUP BY Codice HAVING SUM( Scarico ) &gt; 1000 </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>Dall'esempio gi&#224; visto in figura <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2861.htm#almlanchor16191">692.25</a> risulterebbe escluso l'articolo <samp>rond50</samp>.</p> <h2>692.3 &nbsp; <a name="almltitle6096"></a><a name="almlanchor16194"></a> Trasferimento di dati in un'altra relazione </h2> <p>Alcune forme particolari di interrogazioni <a name="almlindex19141"></a>SQL possono essere utilizzate per inserire dati in relazioni esistenti o per crearne di nuove.</p> <h3>692.3.1 &nbsp; <a name="almltitle6097"></a><a name="almlanchor16195"></a> Creazione di una nuova relazione a partire da altre </h3> <p>L'istruzione <samp>SELECT</samp> pu&#242; servire per creare una nuova relazione a partire dai dati ottenuti dalla sua interrogazione.</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>SELECT <var>specificazione_dell'attributo_1</var><strong class="syn">[</strong>,...<var>specificazione_dell'attributo_n</var><strong class="syn">]</strong> INTO TABLE <var>relazione_da_generare</var> FROM <var>specificazione_della_relazione_1</var><strong class="syn">[</strong>,...<var>specificazione_della_relazione_n</var><strong class="syn">]</strong> <strong class="syn">[</strong>WHERE <var>condizione</var><strong class="syn">]</strong> </pre> </td></tr></tbody> </table> <p>L'esempio seguente crea la relazione <samp>Mia_prova</samp> come risultato della fusione delle relazioni <samp>Indirizzi</samp> e <samp>Presenze</samp>.</p> <table summary="" id="almlanchor16196"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>SELECT Presenze.Giorno, Presenze.Ingresso, Presenze.Uscita, Indirizzi.Cognome, Indirizzi.Nome INTO TABLE Mia_prova FROM Presenze, Indirizzi WHERE Presenze.Codice = Indirizzi.Codice; </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <h3>692.3.2 &nbsp; <a name="almltitle6098"></a><a name="almlanchor16197"></a> Inserimento in una relazione esistente <a name="almlindex19142"></a> </h3> <p>L'inserimento di dati in una relazione esistente prelevando da dati contenuti in altre, pu&#242; essere fatta attraverso l'istruzione <samp>INSERT</samp> sostituendo la clausola <samp>VALUES</samp> con un'interrogazione (<samp>SELECT</samp>).</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>INSERT INTO <var>nome_relazione</var> <strong class="syn">[</strong>(<var>attributo_1</var>...<var>attributo_n</var>)<strong class="syn">]</strong> SELECT <var>espressione_1</var>, ... <var>espressione_n</var> FROM <var>relazioni_di_origine</var> <strong class="syn">[</strong>WHERE <var>condizione</var><strong class="syn">]</strong> </pre> </td></tr></tbody> </table> <p>L'esempio seguente aggiunge alla relazione dello storico delle presenze le registrazioni vecchie che poi vengono cancellate.</p> <table summary="" id="almlanchor16198"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>INSERT INTO PresenzeStorico ( PresenzeStorico.Codice, PresenzeStorico.Giorno, PresenzeStorico.Ingresso, PresenzeStorico.Uscita ) SELECT Presenze.Codice, Presenze.Giorno, Presenze.Ingresso, Presenze.Uscita FROM Presenze WHERE Presenze.Giorno &lt;= '01/01/1999'; DELETE FROM Presenze WHERE Giorno &lt;= '01/01/1999'; </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <h2>692.4 &nbsp; <a name="almltitle6099"></a><a name="almlanchor16199"></a> Viste <a name="almlindex19143"></a> <a name="almlindex19144"></a> </h2> <p>Le viste sono delle relazioni virtuali ottenute a partire da relazioni vere e proprie o da altre viste, purch&#233; non si formino ricorsioni. Il concetto non dovrebbe risultare strano. In effetti, il risultato delle interrogazioni &#232; sempre in forma di relazione. La vista crea una sorta di interrogazione permanente che acquista la personalit&#224; di una relazione normale.</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>CREATE VIEW <var>nome_vista</var> <strong class="syn">[</strong>(<var>attributo_1</var><strong class="syn">[</strong>,...<var>attributo_n</var>)<strong class="syn">]</strong><strong class="syn">]</strong> AS <var>richiesta</var> </pre> </td></tr></tbody> </table> <p>Dopo la parola chiave <samp>AS</samp> deve essere indicato ci&#242; che compone un'istruzione <samp>SELECT</samp>. L'esempio seguente, genera la vista dei movimenti di magazzino del solo articolo <samp>vite30</samp>.</p> <table summary="" id="almlanchor16200"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>CREATE VIEW Movimenti_Vite30 AS SELECT Codice, Data, Carico, Scarico FROM Movimenti WHERE Codice = 'vite30' </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>L'eliminazione di una vista si ottiene con l'istruzione <samp>DROP VIEW</samp>, come illustrato dallo schema sintattico seguente:</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>DROP VIEW <var>nome_vista</var> </pre> </td></tr></tbody> </table> <p>Volendo eliminare la vista <samp>Movimenti_Vite30</samp>, si pu&#242; intervenire semplicemente come nell'esempio seguente:</p> <table summary="" id="almlanchor16201"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>DROP VIEW Movimenti_Vite30 </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <h2>692.5 &nbsp; <a name="almltitle6100"></a><a name="almlanchor16202"></a> Cursori </h2> <p>Quando il risultato di un'interrogazione <a name="almlindex19145"></a>SQL deve essere gestito all'interno di un programma, si pone un problema nel momento in cui ci&#242; che si ottiene &#232; composto da pi&#249; di una sola tupla. Per poter scorrere un elenco ottenuto attraverso un'istruzione <samp>SELECT</samp>, tupla per tupla, si deve usare un <strong><em>cursore</em></strong>.</p> <p>La dichiarazione e l'utilizzo di un cursore avviene all'interno di una transazione. Quando la transazione si chiude attraverso un'istruzione <samp>COMMIT</samp> o <samp>ROLLBACK</samp>, si chiude anche il cursore.</p> <h3>692.5.1 &nbsp; <a name="almltitle6101"></a><a name="almlanchor16203"></a> Dichiarazione e apertura <a name="almlindex19146"></a> <a name="almlindex19147"></a> </h3> <p>L'<a name="almlindex19148"></a>SQL prevede due fasi prima dell'utilizzo di un cursore: la dichiarazione e la sua apertura:</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>DECLARE <var>cursore</var> <strong class="syn">[</strong>INSENSITIVE<strong class="syn">]</strong> <strong class="syn">[</strong>SCROLL<strong class="syn">]</strong> CURSOR FOR SELECT ... </pre> </td></tr></tbody> </table> <table class="syntax" summary=""> <tbody><tr><td> <pre>OPEN <var>cursore</var> </pre> </td></tr></tbody> </table> <p>Nella dichiarazione, la parola chiave <samp>INSENSITIVE</samp> serve a stabilire che il risultato dell'interrogazione che si scandisce attraverso il cursore, non deve essere sensibile alle variazioni dei dati originali; la parola chiave <samp>SCROLL</samp> indica che &#232; possibile estrarre pi&#249; tuple simultaneamente attraverso il cursore.</p> <table summary="" id="almlanchor16204"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>DECLARE Mio_cursore CURSOR FOR SELECT Presenze.Giorno, Presenze.Ingresso, Presenze.Uscita, Indirizzi.Cognome, Indirizzi.Nome FROM Presenze, Indirizzi WHERE Presenze.Codice = Indirizzi.Codice; </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>L'esempio mostra la dichiarazione del cursore <samp>Mio_cursore</samp>, abbinato alla selezione degli attributi composti dal collegamento di due relazioni, <samp>Presenze</samp> e <samp>Indirizzi</samp>, dove le tuple devono avere lo stesso numero di codice. Per attivare questo cursore, lo si deve aprire come nell'esempio seguente:</p> <table summary="" id="almlanchor16205"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>OPEN Mio_cursore </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <h3>692.5.2 &nbsp; <a name="almltitle6102"></a><a name="almlanchor16206"></a> Scansione <a name="almlindex19149"></a> </h3> <p>La scansione di un'interrogazione inserita in un cursore, avviene attraverso l'istruzione <samp>FETCH</samp>. Il suo scopo &#232; quello di estrarre una tupla alla volta, in base a una posizione, relativa o assoluta.</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>FETCH <strong class="syn">[</strong> <strong class="syn">[</strong> NEXT <strong class="syn">|</strong> PRIOR <strong class="syn">|</strong> FIRST <strong class="syn">|</strong> LAST <strong class="syn">|</strong> <strong class="syn">{</strong> ABSOLUTE <strong class="syn">|</strong> RELATIVE <strong class="syn">}</strong> <var>n</var> <strong class="syn">]</strong> FROM <var>cursore</var> <strong class="syn">]</strong> INTO :<var>variabile</var> <strong class="syn">[</strong>,...<strong class="syn">]</strong> </pre> </td></tr></tbody> </table> <p>Le parole chiave <samp>NEXT</samp>, <samp>PRIOR</samp>, <samp>FIRST</samp>, <samp>LAST</samp>, permettono rispettivamente di ottenere la tupla successiva, quella precedente, la prima e l'ultima. Le parole chiave <samp>ABSOLUTE</samp> e <samp>RELATIVE</samp> sono seguite da un numero, corrispondente alla scelta della tupla <var>n</var>-esima, rispetto all'inizio del gruppo per il quale &#232; stato definito il cursore (<samp>ABSOLUTE</samp>), oppure della tupla <var>n</var>-esima rispetto all'ultima tupla estratta da un'istruzione <samp>FETCH</samp> precedente.</p> <p>Le variabili indicate dopo la parola chiave <samp>INTO</samp>, che in particolare sono precedute da due punti (<samp>:</samp>), ricevono ordinatamente il contenuto dei vari attributi della tupla estratta. Naturalmente, le variabili in questione devono appartenere a un linguaggio di programmazione che incorpora l'<a name="almlindex19150"></a>SQL, dal momento che l'<a name="almlindex19151"></a>SQL stesso non fornisce questa possibilit&#224;.</p> <table summary="" id="almlanchor16207"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>FETCH NEXT FROM Mio_cursore </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>L'esempio mostra l'uso tipico di questa istruzione, dove si legge la tupla successiva (se non ne sono state lette fino a questo punto, si tratta della prima), dal cursore dichiarato e aperto precedentemente. L'esempio seguente &#232; identico dal punto di vista funzionale.</p> <table summary="" id="almlanchor16208"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>FETCH RELATIVE 1 FROM Mio_cursore </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>I due esempi successivi sono equivalenti e servono a ottenere la tupla precedente.</p> <table summary="" id="almlanchor16209"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>FETCH PRIOR FROM Mio_cursore </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <table summary="" id="almlanchor16210"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>FETCH RELATIVE -1 FROM Mio_cursore </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <h3>692.5.3 &nbsp; <a name="almltitle6103"></a><a name="almlanchor16211"></a> Chiusura <a name="almlindex19152"></a> </h3> <p>Il cursore, al termine dell'utilizzo, deve essere chiuso:</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>CLOSE <var>cursore</var> </pre> </td></tr></tbody> </table> <p>Seguendo gli esempi visti in precedenza, per chiudere il cursore <samp>Mio_cursore</samp> basta l'istruzione seguente:</p> <table summary="" id="almlanchor16212"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>CLOSE Mio_cursore </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <hr> <p>Appunti di informatica libera 2008 --- <em>Copyright &#169; 2000-2008 Daniele Giacomini -- &lt;<em>appunti2&#8201;(ad)&#8201;gmail&#183;com</em>&gt;</em></p> <hr> <p>Dovrebbe essere possibile fare riferimento a questa pagina anche con il nome <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/linguaggio_sql_dml.htm">linguaggio_sql_dml.htm</a></p> <p> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2862.htm">[successivo]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2860.htm">[precedente]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2.htm">[inizio]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a21088.htm">[fine]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a21.htm">[indice generale]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a22.htm">[indice ridotto]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a21088.htm">[indice analitico]</a> </p> <p class="validator"><a href="http://validator.w3.org/check/referer"><img src="SQL-DML_files/v15445.png" alt="Valid ISO-HTML!"></a></p> <p class="validator"><a href="http://jigsaw.w3.org/css-validator/check/referer"><img src="SQL-DML_files/vcss.png" alt="CSS validator!"></a></p> </body></html>
///(Fine file: SQL-DML.htm)

///File: SQL-DCL.htm
<!DOCTYPE HTML PUBLIC "ISO/IEC 15445:2000//DTD HTML//EN"> <html lang="it"><head> <meta http-equiv="Content-Type" content="text/html;charset=us-ascii"> <meta name="Generator" content="Alml"> <meta name="Description" content="GNU/Linux e altro software libero"> <meta name="Keywords" content="Linux, GNU/Linux, Unix, software, software libero, free software"> <meta name="Author" content="Daniele Giacomini &nbsp;&nbsp; &lt;appunti2&#8201;(ad)&#8201;gmail&#183;com&gt;"> <meta name="Date" content="2008"> <meta name="Resource-type" content="Document" lang="en"> <meta name="Revisit-after" content="15 days" lang="en"> <meta name="Robots" content="ALL"><title>a2 --- Linguaggio SQL: DCL</title> <style type="text/css"> <!-- BODY { background-color: rgb(255, 255, 255); } H1 { text-align: right; color: rgb(230, 100, 180); /* */ } SAMP { quotes: "'" "'"; font-weight: bold; } SAMP:before { content: open-quote; } SAMP:after { content: close-quote; } CODE.file { quotes: "'" "'"; } CODE.file:before { content: open-quote; } CODE.file:after { content: close-quote; } P.syntax { width: auto; text-align: left } P.caption { text-align: left; font-style: italic; width: 100%; background-color: rgb(211, 211, 211); /* light gray */ } P.command { text-align: left; width: auto; /* width: 100%; */ border-style: none; background-color: rgb(255, 170, 255); /* light magenta */ } EM.promptinfo { text-align: left; width: auto; border-style: none; background-color: rgb(0, 255, 0); /* green */ font-size: 80%; } P.fullpagepicture { text-align: center; } P { /* text-align: justify */ text-align: left } P.validator { border-style: none; } P.testtime { text-align: right; } P.testsend { text-align: right; } DIV.listing { width: auto; background-color: rgb(173, 216, 230); /* light blue */ } DIV.object { width: auto; } TABLE.frame { width: 100%; border-color: black; border-style: solid; background-color: yellow; border-width: thin; } TABLE.pre { /* width: 100%; */ width: auto; border-color: black; border-style: solid; background-color: rgb(211, 211, 211); /* light gray */ border-width: thin; } TABLE.syntax { /* width: 100%; */ width: auto; border-color: black; border-style: solid; background-color: rgb(170, 255, 255); /* light cyan */ border-width: thin; } TABLE.figurewrapper { width: 100%; border-style: none; } TABLE.figure { width: 100%; border-color: black; border-style: solid; background-color: rgb(211, 211, 211); /* light gray */ border-width: thin; } TABLE.listing { /* width: 100%; */ width: auto; border-color: black; border-style: solid; border-width: thin; } TABLE.object { /* width: 100%; */ width: auto; border-color: green; border-style: solid; border-width: thin; } TABLE.table { width: 100%; border-color: black; border-style: solid; border-width: thin; background-color: rgb(190, 255, 190); /* light green */ } THEAD.border { background-color: rgb(224, 255, 255); /* light cyan */ border-color: black; border-style: solid; border-width: thin; } THEAD.noborder { background-color: rgb(224, 255, 255); /* light cyan */ border-color: black; border-style: solid; border-width: thin; } TBODY.border { border-color: black; border-style: solid; border-width: thin; } TBODY.noborder { border-style: none; } TD.border { border-color: black; border-style: solid; border-width: thin; } TR.noborder { border-style: none; } TABLE.testinfo { width: 100%; border-color: black; border-style: solid; border-width: thin; } TBODY.testinfo { border-style: none; } COL.testinfolabel { border-style: none; width: 300px; } COL.testinfofield { border-style: none; width: 400px; } TD.testinfo { border-style: none; } STRONG.syn { font-size: 120%; } STRONG.newline { font-size: 162%; } SPAN.big { font-size: 120%; } SPAN.small { font-size: 80%; } SPAN.visible_label { font-size: 75%; font-style: italic; font-weight: bold; color: blue; border-color: green; border-style: solid; border-width: thin; } SPAN.command { background-color: rgb(255, 170, 255); /* light magenta */ } SPAN.posix { text-decoration: underline; } HR.object { color: green; } A:hover { color: #fff; background: #00c; } COL.widthpixel243 { width: 243px; } COL.widthpixel1031 { width: 1031px; } --> </style> <link rel="Start" title="Start" href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2.htm"> <link rel="Prev" title="Previous" href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2861.htm"> <link rel="Next" title="Next" href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2863.htm"></head><body> <p> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2863.htm">[successivo]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2861.htm">[precedente]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2.htm">[inizio]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a21088.htm">[fine]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a21.htm">[indice generale]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a22.htm">[indice ridotto]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a21088.htm">[indice analitico]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2855.htm">[volume]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2856.htm">[parte]</a> </p> <hr> <h1>Capitolo 693. &nbsp; <a name="almltitle6104"></a><a name="almlanchor16213"></a> Linguaggio <a name="almlindex19153"></a>SQL: DCL <a name="almlindex19154"></a> <a name="almlindex19155"></a> <a name="almlindex19156"></a> </h1> <p>DCL, ovvero <em>Data control language</em>, &#232; il linguaggio usato per il &#171;controllo&#187; delle basi&nbsp;di&nbsp;dati. In questo capitolo viene trattato il linguaggio <a name="almlindex19157"></a>SQL per ci&#242; che riguarda la gestione delle basi&nbsp;di&nbsp;dati, degli utenti, dei privilegi assegnati loro e il controllo delle transazioni.</p> <h2>693.1 &nbsp; <a name="almltitle6105"></a><a name="almlanchor16214"></a> Gestione delle utenze <a name="almlindex19158"></a> <a name="almlindex19159"></a> <a name="almlindex19160"></a> </h2> <p>La gestione degli accessi in una base&nbsp;di&nbsp;dati &#232; molto importante e potenzialmente indipendente dall'eventuale gestione degli utenti del sistema operativo sottostante. Per quanto riguarda i sistemi Unix, il DBMS pu&#242; riutilizzare la definizione degli utenti del sistema operativo, farvi riferimento, oppure astrarsi completamente (spesso vale questa ultima ipotesi).</p> <p>Un DBMS <a name="almlindex19161"></a>SQL richiede la presenza di almeno un amministratore complessivo, che come tale abbia sempre tutti i privilegi necessari a intervenire come vuole nel DBMS. Il nome simbolico predefinito per questo utente dal linguaggio <a name="almlindex19162"></a>SQL standard &#232; <samp>_SYSTEM</samp>.</p> <p>Il sistema di definizione e controllo delle utenze &#232; esterno al linguaggio <a name="almlindex19163"></a>SQL standard; tuttavia, i DBMS principali utilizzano istruzioni abbastanza uniformi per questo scopo.</p> <p>Per la creazione di un utente si dispone normalmente dell'istruzione <samp>CREATE USER</samp>, con opzioni che dipendono dalle caratteristiche particolari del DBMS, nella gestione delle utenze. I due modelli sintattici successivi si riferiscono, rispettivamente, a <a name="almlindex19164"></a>Oracle e a PostgreSQL, ma omettono varie opzioni specifiche e presumono che l'utente debba essere identificato attraverso una parola&nbsp;d'ordine:</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>CREATE USER <var>nome_utente</var> IDENTIFIED BY '<var>parola_d'ordine</var>' </pre> </td></tr></tbody> </table> <table class="syntax" summary=""> <tbody><tr><td> <pre>CREATE USER <var>nome_utente</var> <strong class="syn">[</strong>WITH PASSWORD '<var>parola_d'ordine</var>'<strong class="syn">]</strong> </pre> </td></tr></tbody> </table> <p>Nel caso di MySQL, invece di introdurre un'istruzione che non esiste nello standard, si estende quella con cui si concedono i privilegi (descritta in un'altra sezione):</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>GRANT <var>privilegi</var> ON <var>risorsa</var><strong class="syn">[</strong>,...<strong class="syn">]</strong> TO <var>utente</var> IDENTIFIED BY '<var>parola_d'ordine</var>' <strong class="syn">[</strong>WITH GRANT OPTION<strong class="syn">]</strong> </pre> </td></tr></tbody> </table> <p>In tal modo, attribuendo dei privilegi a un utente, se questo non esiste ancora, viene creato contestualmente. Si osservi comunque, che le versioni pi&#249; recenti di MySQL dispongono di un'istruzione <samp>CREATE USER</samp> simile a quella di altri DBMS.</p> <p>Per l'eliminazione di un utente si dispone normalmente dell'istruzione <samp>DROP USER</samp>, con opzioni che di solito consentono l'eliminazione contestuale di tutto ci&#242; che appartiene a tale utente:</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>DROP USER <var>nome_utente</var> </pre> </td></tr></tbody> </table> <p>Per modificare la parola&nbsp;d'ordine di un utente, si dispone normalmente dell'istruzione <samp>ALTER USER</samp>, con la quale si potrebbero cambiare anche altre opzioni legate ai privilegi generali di cui pu&#242; disporre tale utente. I due modelli sintattici successivi si riferiscono, rispettivamente, a <a name="almlindex19165"></a>Oracle e a PostgreSQL, omettendo opzioni che non sono indispensabili:</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>ALTER USER <var>nome_utente</var> IDENTIFIED BY '<var>parola_d'ordine</var>' </pre> </td></tr></tbody> </table> <table class="syntax" summary=""> <tbody><tr><td> <pre>ALTER USER <var>nome_utente</var> <strong class="syn">[</strong>WITH PASSWORD '<var>parola_d'ordine</var>'<strong class="syn">]</strong> </pre> </td></tr></tbody> </table> <p>Nel caso di MySQL si usa una forma differente:</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>SET PASSWORD FOR <var>nome_utente</var> = PASSWORD('<var>parola_d'ordine</var>') </pre> </td></tr></tbody> </table> <h2>693.2 &nbsp; <a name="almltitle6106"></a><a name="almlanchor16215"></a> Gestione delle basi&nbsp;di&nbsp;dati <a name="almlindex19166"></a> </h2> <p>La creazione e l'eliminazione delle basi&nbsp;di&nbsp;dati &#232; una funzione non considerata dallo standard <a name="almlindex19167"></a>SQL, anche se &#232; normale che un DBMS consenta la gestione di pi&#249; basi&nbsp;di&nbsp;dati simultaneamente. Pertanto, i vari DBMS offrono delle istruzioni <a name="almlindex19168"></a>SQL abbastanza uniformi:</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>CREATE DATABASE <var>nome_base_di_dati</var> </pre> </td></tr></tbody> </table> <p>Di solito, salvo indicazione diversa derivante da opzioni particolari aggiunte all'istruzione, l'utente che crea la base&nbsp;di&nbsp;dati ne diviene il proprietario, con ogni facolt&#224; sulla stessa, anche quella di eliminarla.</p> <p>&#200; il caso di osservare che uno dei problemi tecnici da considerare nella creazione di una base&nbsp;di&nbsp;dati sta nel definire la codifica da usare per la memorizzazione delle informazioni testuali. Di solito, questo genere di cose viene definito tramite delle opzioni specifiche, che si aggiungono al modello sintetico e generalizzato mostrato qui.</p> <p>L'eliminazione di una base&nbsp;di&nbsp;dati richiede generalmente un'istruzione altrettanto semplice:</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>DROP DATABASE <var>nome_base_di_dati</var> </pre> </td></tr></tbody> </table> <p>La differenza pi&#249; importante tra i vari DBMS consiste nel modo di comportarsi di fronte a questo comando, quando la base&nbsp;di&nbsp;dati non &#232; vuota. Se esiste un contenuto, la cancellazione potrebbe essere rifiutata, oppure potrebbe essere ammessa se si aggiungono opzioni specifiche che servono a confermarne l'eliminazione. Tuttavia, non si pu&#242; contare su un controllo di questo genere e la cancellazione di una base&nbsp;di&nbsp;dati richiede sempre la dovuta prudenza.</p> <h2>693.3 &nbsp; <a name="almltitle6107"></a><a name="almlanchor16216"></a> Gestione dei privilegi standard <a name="almlindex19169"></a> <a name="almlindex19170"></a> </h2> <p>L'utente che crea una relazione, o un'altra risorsa, &#232; il suo creatore. Su tale risorsa &#232; l'unico utente che possa modificarne la struttura e che possa eliminarla. In pratica &#232; l'unico che possa usare le istruzioni <samp>DROP</samp> e <samp>ALTER</samp>. Chi crea una relazione, o un'altra risorsa, pu&#242; concedere o revocare i privilegi degli altri utenti su di essa.</p> <p>I privilegi che si possono concedere o revocare su una risorsa sono di vario tipo, espressi attraverso una parola chiave particolare. &#200; bene considerare i casi seguenti:</p> <table summary="" id="almlanchor16217"> <tbody><tr><td> <div class="object"> <table class="table" summary=""> <colgroup><col class="widthpixel243"><col class="widthpixel1031"></colgroup> <thead class="border"> <tr><td class="border">Privilegio </td><td class="border">Descrizione </td></tr> </thead> <tbody class="border"> <tr><td class="border"> <pre>SELECT </pre> </td><td class="border">rappresenta l'operazione di lettura del valore di un oggetto della risorsa, per esempio dei valori di una tupla da una relazione (in pratica si riferisce all'uso dell'istruzione <samp>SELECT</samp>); </td></tr> <tr><td class="border"> <pre>INSERT </pre> </td><td class="border">rappresenta l'azione di inserire un nuovo oggetto nella risorsa, come l'inserimento di una tupla in una relazione; </td></tr> <tr><td class="border"> <pre>UPDATE </pre> </td><td class="border">rappresenta l'operazione di aggiornamento del valore di un oggetto della risorsa, per esempio la modifica del contenuto di una tupla di una relazione; </td></tr> <tr><td class="border"> <pre>DELETE </pre> </td><td class="border">rappresenta l'eliminazione di un oggetto dalla risorsa, come la cancellazione di una tupla da una relazione; </td></tr> <tr><td class="border"> <pre>ALL PRIVILEGES </pre> </td><td class="border">rappresenta simultaneamente tutti i privilegi possibili riferiti a un oggetto. </td></tr> </tbody> </table> </div> </td></tr></tbody> </table> <p>I privilegi su una relazione, o su un'altra risorsa, vengono concessi attraverso l'istruzione <samp>GRANT</samp>:</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>GRANT <var>privilegi</var> ON <var>risorsa</var><strong class="syn">[</strong>,...<strong class="syn">]</strong> TO <var>utenti</var> <strong class="syn">[</strong>WITH GRANT OPTION<strong class="syn">]</strong> </pre> </td></tr></tbody> </table> <p>Nella maggior parte dei casi, le risorse da controllare coincidono con una relazione. L'esempio seguente permette all'utente <samp>Pippo</samp> di leggere il contenuto della relazione <samp>Movimenti</samp>:</p> <table summary="" id="almlanchor16218"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>GRANT SELECT ON Movimenti TO Pippo </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>L'esempio seguente, concede tutti i privilegi sulla relazione <samp>Movimenti</samp> agli utenti <samp>Pippo</samp> e <samp>Arturo</samp>:</p> <table summary="" id="almlanchor16219"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>GRANT ALL PRIVILEGES ON Movimenti TO Pippo, Arturo </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>L'opzione <samp>WITH GRANT OPTION</samp> permette agli utenti presi in considerazione di concedere a loro volta tali privilegi ad altri utenti. L'esempio seguente concede all'utente <samp>Pippo</samp> di accedere in lettura al contenuto della relazione <samp>Movimenti</samp> e gli permette di concedere lo stesso privilegio ad altri:</p> <table summary="" id="almlanchor16220"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>GRANT SELECT ON Movimenti TO Pippo WITH GRANT OPTION </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>I privilegi su una relazione, o un'altra risorsa, vengono revocati attraverso l'istruzione <samp>REVOKE</samp>:</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>REVOKE <var>privilegi</var> ON <var>risorsa</var><strong class="syn">[</strong>,...<strong class="syn">]</strong> FROM <var>utenti</var> </pre> </td></tr></tbody> </table> <p>L'esempio seguente toglie all'utente <samp>Pippo</samp> il permesso di accedere in lettura al contenuto della relazione <samp>Movimenti</samp>:</p> <table summary="" id="almlanchor16221"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>REVOKE SELECT ON Movimenti FROM Pippo </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>L'esempio seguente toglie tutti i privilegi sulla relazione <samp>Movimenti</samp> agli utenti <samp>Pippo</samp> e <samp>Arturo</samp>:</p> <table summary="" id="almlanchor16222"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>REVOKE ALL PRIVILEGES ON Movimenti FROM Pippo, Arturo </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <h2>693.4 &nbsp; <a name="almltitle6108"></a><a name="almlanchor16223"></a> Controllo delle transazioni <a name="almlindex19171"></a> <a name="almlindex19172"></a> </h2> <p>Una transazione <a name="almlindex19173"></a>SQL, &#232; una sequenza di istruzioni che rappresenta un corpo unico dal punto di vista della memorizzazione effettiva dei dati. In altre parole, secondo l'<a name="almlindex19174"></a>SQL, la registrazione delle modifiche apportate alla base&nbsp;di&nbsp;dati avviene in modo asincrono, raggruppando assieme l'effetto di gruppi di istruzioni determinati.</p> <p>Una transazione inizia nel momento in cui l'interprete <a name="almlindex19175"></a>SQL incontra, generalmente, l'istruzione <samp>START TRANSACTION</samp>, terminando con l'istruzione <samp>COMMIT</samp>, oppure <samp>ROLLBACK</samp>: nel primo caso si conferma la transazione che viene memorizzata regolarmente, mentre nel secondo si richiede di annullare le modifiche apportate dalla transazione.</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>START TRANSACTION </pre> </td></tr></tbody> </table> <table class="syntax" summary=""> <tbody><tr><td> <pre>COMMIT <strong class="syn">[</strong>WORK<strong class="syn">]</strong> </pre> </td></tr></tbody> </table> <table class="syntax" summary=""> <tbody><tr><td> <pre>ROLLBACK <strong class="syn">[</strong>WORK<strong class="syn">]</strong> </pre> </td></tr></tbody> </table> <p>Stando cos&#236; le cose, si intende la necessit&#224; di utilizzare regolarmente l'istruzione <samp>COMMIT</samp> per memorizzare i dati quando non esiste pi&#249; la necessit&#224; di annullare le modifiche.</p> <table summary="" id="almlanchor16224"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>START TRANSACTION ... COMMIT INSERT INTO Indirizzi VALUES ( 01, 'Pallino', 'Pinco', 'Via Biglie 1', '0222,222222' ) COMMIT </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>L'esempio mostra un uso intensivo dell'istruzione <samp>COMMIT</samp>, dove dopo l'inserimento di una tupla nella relazione <samp>Indirizzi</samp>, viene confermata immediatamente la transazione.</p> <table summary="" id="almlanchor16225"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>START TRANSACTION ... COMMIT INSERT INTO Indirizzi VALUES ( 01, 'Pallino', 'Pinco', 'Via Biglie 1', '0222,222222' ) ROLLBACK </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>Questo esempio mostra un ripensamento (per qualche motivo). Dopo l'inserimento di una tupla nella relazione <samp>Indirizzi</samp>, viene annullata la transazione, riportando la relazione allo stato precedente.</p> <hr> <p>Appunti di informatica libera 2008 --- <em>Copyright &#169; 2000-2008 Daniele Giacomini -- &lt;<em>appunti2&#8201;(ad)&#8201;gmail&#183;com</em>&gt;</em></p> <hr> <p>Dovrebbe essere possibile fare riferimento a questa pagina anche con il nome <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/linguaggio_sql_dcl.htm">linguaggio_sql_dcl.htm</a></p> <p> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2863.htm">[successivo]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2861.htm">[precedente]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2.htm">[inizio]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a21088.htm">[fine]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a21.htm">[indice generale]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a22.htm">[indice ridotto]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a21088.htm">[indice analitico]</a> </p> <p class="validator"><a href="http://validator.w3.org/check/referer"><img src="SQL-DCL_files/v15445.png" alt="Valid ISO-HTML!"></a></p> <p class="validator"><a href="http://jigsaw.w3.org/css-validator/check/referer"><img src="SQL-DCL_files/vcss.png" alt="CSS validator!"></a></p> </body></html>
///(Fine file: SQL-DCL.htm)

///File: SQL-DDL.htm
<!DOCTYPE HTML PUBLIC "ISO/IEC 15445:2000//DTD HTML//EN"> <html lang="it"><head> <meta http-equiv="Content-Type" content="text/html;charset=us-ascii"> <meta name="Generator" content="Alml"> <meta name="Description" content="GNU/Linux e altro software libero"> <meta name="Keywords" content="Linux, GNU/Linux, Unix, software, software libero, free software"> <meta name="Author" content="Daniele Giacomini &nbsp;&nbsp; &lt;appunti2&#8201;(ad)&#8201;gmail&#183;com&gt;"> <meta name="Date" content="2008"> <meta name="Resource-type" content="Document" lang="en"> <meta name="Revisit-after" content="15 days" lang="en"> <meta name="Robots" content="ALL"><title>a2 --- Linguaggio SQL: DDL</title> <style type="text/css"> <!-- BODY { background-color: rgb(255, 255, 255); } H1 { text-align: right; color: rgb(230, 100, 180); /* */ } SAMP { quotes: "'" "'"; font-weight: bold; } SAMP:before { content: open-quote; } SAMP:after { content: close-quote; } CODE.file { quotes: "'" "'"; } CODE.file:before { content: open-quote; } CODE.file:after { content: close-quote; } P.syntax { width: auto; text-align: left } P.caption { text-align: left; font-style: italic; width: 100%; background-color: rgb(211, 211, 211); /* light gray */ } P.command { text-align: left; width: auto; /* width: 100%; */ border-style: none; background-color: rgb(255, 170, 255); /* light magenta */ } EM.promptinfo { text-align: left; width: auto; border-style: none; background-color: rgb(0, 255, 0); /* green */ font-size: 80%; } P.fullpagepicture { text-align: center; } P { /* text-align: justify */ text-align: left } P.validator { border-style: none; } P.testtime { text-align: right; } P.testsend { text-align: right; } DIV.listing { width: auto; background-color: rgb(173, 216, 230); /* light blue */ } DIV.object { width: auto; } TABLE.frame { width: 100%; border-color: black; border-style: solid; background-color: yellow; border-width: thin; } TABLE.pre { /* width: 100%; */ width: auto; border-color: black; border-style: solid; background-color: rgb(211, 211, 211); /* light gray */ border-width: thin; } TABLE.syntax { /* width: 100%; */ width: auto; border-color: black; border-style: solid; background-color: rgb(170, 255, 255); /* light cyan */ border-width: thin; } TABLE.figurewrapper { width: 100%; border-style: none; } TABLE.figure { width: 100%; border-color: black; border-style: solid; background-color: rgb(211, 211, 211); /* light gray */ border-width: thin; } TABLE.listing { /* width: 100%; */ width: auto; border-color: black; border-style: solid; border-width: thin; } TABLE.object { /* width: 100%; */ width: auto; border-color: green; border-style: solid; border-width: thin; } TABLE.table { width: 100%; border-color: black; border-style: solid; border-width: thin; background-color: rgb(190, 255, 190); /* light green */ } THEAD.border { background-color: rgb(224, 255, 255); /* light cyan */ border-color: black; border-style: solid; border-width: thin; } THEAD.noborder { background-color: rgb(224, 255, 255); /* light cyan */ border-color: black; border-style: solid; border-width: thin; } TBODY.border { border-color: black; border-style: solid; border-width: thin; } TBODY.noborder { border-style: none; } TD.border { border-color: black; border-style: solid; border-width: thin; } TR.noborder { border-style: none; } TABLE.testinfo { width: 100%; border-color: black; border-style: solid; border-width: thin; } TBODY.testinfo { border-style: none; } COL.testinfolabel { border-style: none; width: 300px; } COL.testinfofield { border-style: none; width: 400px; } TD.testinfo { border-style: none; } STRONG.syn { font-size: 120%; } STRONG.newline { font-size: 162%; } SPAN.big { font-size: 120%; } SPAN.small { font-size: 80%; } SPAN.visible_label { font-size: 75%; font-style: italic; font-weight: bold; color: blue; border-color: green; border-style: solid; border-width: thin; } SPAN.command { background-color: rgb(255, 170, 255); /* light magenta */ } SPAN.posix { text-decoration: underline; } HR.object { color: green; } A:hover { color: #fff; background: #00c; } COL.widthpixel487 { width: 487px; } COL.widthpixel787 { width: 787px; } COL.widthpixel243 { width: 243px; } COL.widthpixel1031 { width: 1031px; } --> </style> <link rel="Start" title="Start" href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2.htm"> <link rel="Prev" title="Previous" href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2859.htm"> <link rel="Next" title="Next" href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2861.htm"></head><body> <p> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2861.htm">[successivo]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2859.htm">[precedente]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2.htm">[inizio]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a21088.htm">[fine]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a21.htm">[indice generale]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a22.htm">[indice ridotto]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a21088.htm">[indice analitico]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2855.htm">[volume]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2856.htm">[parte]</a> </p> <hr> <h1>Capitolo 691. &nbsp; <a name="almltitle6067"></a><a name="almlanchor16112"></a> Linguaggio <a name="almlindex19106"></a>SQL: DDL <a name="almlindex19107"></a> <a name="almlindex19108"></a> <a name="almlindex19109"></a> </h1> <p>DDL, ovvero <em>Data definition language</em>, &#232; il linguaggio usato per definire la struttura dei dati (in una base&nbsp;di&nbsp;dati). In questo capitolo viene trattato il linguaggio <a name="almlindex19110"></a>SQL per ci&#242; che riguarda specificatamente i dati, la loro creazione e la loro distruzione.</p> <h2>691.1 &nbsp; <a name="almltitle6068"></a><a name="almlanchor16113"></a> Tipi di dati </h2> <p>I tipi di dati gestibili con il linguaggio <a name="almlindex19111"></a>SQL sono molti. Fondamentalmente si possono distinguere tipi contenenti: valori numerici, stringhe e informazioni data-orario. Nelle sezioni seguenti vengono descritti solo alcuni dei tipi definiti dallo standard.</p> <h3>691.1.1 &nbsp; <a name="almltitle6069"></a><a name="almlanchor16114"></a> Stringhe di caratteri <a name="almlindex19112"></a> </h3> <p>Si distinguono due tipi di stringhe di caratteri in <a name="almlindex19113"></a>SQL: quelle a dimensione fissa, completate a destra dal carattere spazio, e quelle a dimensione variabile.</p> <table summary="" id="almlanchor16115"> <tbody><tr><td> <div class="object"> <table class="table" summary=""> <colgroup><col class="widthpixel487"><col class="widthpixel787"></colgroup> <thead class="border"> <tr><td class="border">Sintassi </td><td class="border">Descrizione </td></tr> </thead> <tbody class="border"> <tr><td class="border"> <pre>CHARACTER </pre> <pre>CHARACTER(<var>dimensione</var>) </pre> <pre>CHAR </pre> <pre>CHAR(<var>dimensione</var>) </pre> </td><td class="border">Queste sono le varie sintassi alternative che possono essere utilizzate per definire una stringa di dimensione fissa. Se non viene indicata la dimensione tra parentesi, si intende una stringa di un solo carattere. </td></tr> <tr><td class="border"> <pre>CHARACTER VARYING(<var>dimensione</var>) </pre> <pre>CHAR VARYING(<var>dimensione</var>) </pre> <pre>VARCHAR(<var>dimensione</var>) </pre> </td><td class="border">Una stringa di dimensione variabile pu&#242; essere definita attraverso uno dei tre modi appena elencati. &#200; necessario specificare la dimensione massima che questa stringa pu&#242; avere. Il minimo &#232; rappresentato dalla stringa nulla. </td></tr> </tbody> </table> </div> </td></tr></tbody> </table> <p>Le costanti stringa si esprimono delimitandole attraverso apici singoli, oppure apici doppi, come nell'esempio seguente:</p> <table summary="" id="almlanchor16116"> <tbody><tr><td> <div class="object"> <table class="object" summary=""> <tbody><tr><td> <pre>'Questa &#232; una stringa letterale per SQL' "Anche questa &#232; una stringa letterale per SQL" </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>Non tutti i sistemi <a name="almlindex19114"></a>SQL accettano entrambi i tipi di delimitatori di stringa. In caso di dubbio &#232; bene limitarsi all'uso degli apici singoli; eventualmente, per inserire un apice singolo in una stringa delimitata con apici singoli, dovrebbe essere sufficiente il suo raddoppio. In pratica, per scrivere una stringa del tipo &#171;l'albero&#187;, dovrebbe essere possibile scrivere:</p> <table summary="" id="almlanchor16117"> <tbody><tr><td> <div class="object"> <table class="object" summary=""> <tbody><tr><td> <pre>'l''albero' </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <h3>691.1.2 &nbsp; <a name="almltitle6070"></a><a name="almlanchor16118"></a> Valori numerici <a name="almlindex19115"></a> </h3> <p>I tipi numerici si distinguono in <strong><em>esatti</em></strong> e <strong><em>approssimati</em></strong>, intendendo con la prima definizione quelli di cui si conosce il numero massimo di cifre numeriche intere e decimali, mentre con la seconda si fa riferimento ai tipi a virgola mobile. In ogni caso, le dimensioni massime o la precisione massima che possono avere tali valori dipende dal sistema in cui vengono utilizzati.</p> <table summary="" id="almlanchor16119"> <tbody><tr><td> <div class="object"> <table class="table" summary=""> <colgroup><col class="widthpixel487"><col class="widthpixel787"></colgroup> <thead class="border"> <tr><td class="border">Sintassi </td><td class="border">Descrizione </td></tr> </thead> <tbody class="border"> <tr><td class="border"> <pre>NUMERIC </pre> <pre>NUMERIC(<var>precisione</var><strong class="syn">[</strong>,<var>scala</var><strong class="syn">]</strong>) </pre> </td><td class="border">Il tipo <samp>NUMERIC</samp> permette di definire un valore numerico composto da un massimo di tante cifre numeriche quante indicate dalla precisione, cio&#232; il primo argomento tra parentesi. Se viene specificata anche la scala, si intende riservare quella parte di cifre per quanto appare dopo la virgola. Per esempio, con <samp>NUMERIC(5,2)</samp> si possono rappresentare valori da +999,99 a -999,99.<br> Se non viene specificata la scala, si intende che si tratti solo di valori interi; se non viene specificata nemmeno la precisione, viene usata la definizione predefinita per questo tipo di dati, che dipende dalle caratteristiche del DBMS. </td></tr> <tr><td class="border"> <pre>DECIMAL </pre> <pre>DECIMAL(<var>precisione</var><strong class="syn">[</strong>,<var>scala</var><strong class="syn">]</strong>) </pre> <pre>DEC </pre> <pre>DEC(<var>precisione</var><strong class="syn">[</strong>,<var>scala</var><strong class="syn">]</strong>) </pre> </td><td class="border">Il tipo <samp>DECIMAL</samp> &#232; simile al tipo <samp>NUMERIC</samp>, con la differenza che le caratteristiche della precisione e della scala rappresentano le esigenze minime, mentre il sistema pu&#242; fornire una rappresentazione con precisione o scala maggiore. </td></tr> <tr><td class="border"> <pre>INTEGER </pre> <pre>INT </pre> <pre>SMALLINT </pre> </td><td class="border">I tipi <samp>INTEGER</samp> e <samp>SMALLINT</samp> rappresentano tipi interi la cui dimensione dipende generalmente dalle caratteristiche del sistema operativo e dall'hardware utilizzato. L'unico riferimento sicuro &#232; che il tipo <samp>SMALLINT</samp> permette di rappresentare interi con una dimensione inferiore o uguale al tipo <samp>INTEGER</samp>. </td></tr> <tr><td class="border"> <pre>FLOAT </pre> <pre>FLOAT(<var>precisione</var>) </pre> </td><td class="border">Il tipo <samp>FLOAT</samp> definisce un tipo numerico approssimato (a virgola mobile) con una precisione binaria pari o superiore di quella indicata tra parentesi (se non viene indicata, dipende dal sistema). </td></tr> <tr><td class="border"> <pre>REAL </pre> <pre>DOUBLE PRECISION </pre> </td><td class="border">Il tipo <samp>REAL</samp> e il tipo <samp>DOUBLE PRECISION</samp> sono due tipi a virgola mobile con una precisione prestabilita. Questa precisione dipende dal sistema, ma in generale, il secondo dei due tipi deve essere pi&#249; preciso dell'altro. </td></tr> </tbody> </table> </div> </td></tr></tbody> </table> <p>I valori numerici costanti vengono espressi attraverso la semplice indicazione del numero senza delimitatori. La virgola di separazione della parte intera da quella decimale si esprime normalmente attraverso il punto (<samp>.</samp>), a meno che sia prevista una forma di adattamento alle caratteristiche di configurazione locale.</p> <h3>691.1.3 &nbsp; <a name="almltitle6071"></a><a name="almlanchor16120"></a> Valori Data-orario <a name="almlindex19116"></a> <a name="almlindex19117"></a> <a name="almlindex19118"></a> </h3> <p>I valori data-orario sono di tre tipi e servono rispettivamente a memorizzare un giorno particolare, un orario normale e un'informazione data-ora completa.</p> <table summary="" id="almlanchor16121"> <tbody><tr><td> <div class="object"> <table class="table" summary=""> <colgroup><col class="widthpixel787"><col class="widthpixel487"></colgroup> <thead class="border"> <tr><td class="border">Sintassi </td><td class="border">Descrizione </td></tr> </thead> <tbody class="border"> <tr><td class="border"> <pre>DATE </pre> </td><td class="border">Il tipo <samp>DATE</samp> permette di rappresentare delle date composte dall'informazione anno-mese-giorno. </td></tr> <tr><td class="border"> <pre>TIME </pre> <pre>TIME(<var>precisione</var>) </pre> <pre>TIME WITH TIME ZONE </pre> <pre>TIME(<var>precisione</var>) WITH TIME ZONE </pre> </td><td class="border">Il tipo <samp>TIME</samp> permette di rappresentare un orario particolare, composto da ore-minuti-secondi ed eventualmente frazioni di secondo. Se viene specificata la precisione, si intende definire un numero di cifre per la parte frazionaria dei secondi, altrimenti si intende che non debbano essere memorizzate le frazioni di secondo. </td></tr> <tr><td class="border"> <pre>TIMESTAMP </pre> <pre>TIMESTAMP(<var>precisione</var>) </pre> <pre>TIMESTAMP WITH TIME ZONE </pre> <pre>TIMESTAMP(<var>precisione</var>) WITH TIME ZONE </pre> </td><td class="border">Il tipo <samp>TIMESTAMP</samp> &#232; un'informazione oraria pi&#249; completa del tipo <samp>TIME</samp> in quanto prevede tutte le informazioni, dall'anno ai secondi, oltre alle eventuali frazioni di secondo. </td></tr> </tbody> </table> </div> </td></tr></tbody> </table> <p>Se viene specificata la precisione, si intende definire un numero di cifre per la parte frazionaria dei secondi, altrimenti si intende che non debbano essere memorizzate le frazioni di secondo.</p> <p>L'aggiunta dell'opzione <samp>WITH TIME ZONE</samp> serve a specificare un tipo orario differente, che assieme all'informazione oraria aggiunge lo scostamento, espresso in ore e minuti, dell'ora locale dal tempo universale (UTC). Per esempio, 22:05:10+1:00 rappresenta le 22.05 e 10 secondi dell'ora locale italiana (durante l'inverno), mentre il tempo universale corrispondente sarebbe invece 21:05:10+0:00.</p> <p>Le costanti che rappresentano informazioni data-orario sono espresse come le stringhe, delimitate tra apici. Il sistema DBMS potrebbe ammettere pi&#249; forme differenti per l'inserimento di queste, ma i modi pi&#249; comuni dovrebbero essere quelli espressi dagli esempi seguenti.</p> <table summary="" id="almlanchor16122"> <tbody><tr><td> <div class="object"> <table class="object" summary=""> <tbody><tr><td> <pre>'2007-12-31' '12/31/2007' '31.12.2007' </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>Questi tre esempi rappresentano la stessa data: il 31 dicembre 1999. Per una questione di uniformit&#224;, dovrebbe essere preferibile il primo di questi formati, corrispondente allo stile ISO 8601. Anche gli orari che si vedono sotto, sono aderenti allo stile ISO 8601; in particolare per il fatto che il fuso orario viene indicato attraverso lo scostamento dal tempo universale, invece che attraverso una parola chiave che definisca il fuso dell'ora locale.</p> <table summary="" id="almlanchor16123"> <tbody><tr><td> <div class="object"> <table class="object" summary=""> <tbody><tr><td> <pre>'12:30:50+1.00' '12:30:50.10' '12:30:50' '12:30' </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>Il primo di questa serie di esempi rappresenta un orario composto da ore, minuti e secondi, oltre all'indicazione dello scostamento dal tempo universale (per ottenere il tempo universale deve essere sottratta un'ora). Il secondo esempio mostra un orario composto da ore, minuti, secondi e centesimi di secondo. Il terzo e il quarto sono rappresentazioni normali, in particolare nell'ultimo &#232; stata omessa l'indicazione dei secondi.</p> <table summary="" id="almlanchor16124"> <tbody><tr><td> <div class="object"> <table class="object" summary=""> <tbody><tr><td> <pre>'2007-12-31 12:30:50+1.00' '2007-12-31 12:30:50.10' '2007-12-31 12:30:50' '2007-12-31 12:30' </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>Gli esempi mostrano la rappresentazione di informazioni data-orario complete per il tipo <samp>TIMESTAMP</samp>. La data &#232; separata dall'ora da uno spazio.</p> <h3>691.1.4 &nbsp; <a name="almltitle6072"></a><a name="almlanchor16125"></a> Intervalli di tempo </h3> <p>Quanto mostrato nella sezione precedente rappresenta un valore che indica un momento preciso nel tempo: una data o un'orario, o entrambe le cose. Per rappresentare una durata, si parla di intervalli. Per l'<a name="almlindex19119"></a>SQL si possono gestire gli intervalli a due livelli di precisione: anni e mesi; oppure giorni, ore, minuti, secondi ed eventualmente anche le frazioni di secondo. L'intervallo si indica con la parola chiave <samp>INTERVAL</samp>, seguita eventualmente dalla precisione con cui questo deve essere rappresentato:</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>INTERVAL <strong class="syn">[</strong><var>unit&#224;_di_misura_data_orario</var> <strong class="syn">[</strong>TO <var>unit&#224;_di_misura_data_orario</var><strong class="syn">]</strong><strong class="syn">]</strong> </pre> </td></tr></tbody> </table> <p>In pratica, si pu&#242; indicare che si tratta di un intervallo, senza specificare altro, oppure si possono definire una o due unit&#224; di misura che limitano la precisione di questo (pur restando nei limiti a cui si &#232; gi&#224; accennato). Tanto per fare un esempio concreto, volendo definire un'intervallo che possa esprimere solo ore e minuti, si potrebbe dichiarare con: <samp>INTERVAL HOUR TO MINUTE</samp>. La tabella <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2860.htm#almlanchor16126">691.9</a> elenca le parole chiave che rappresentano queste unit&#224; di misura.</p> <table summary="" id="almlanchor16126"> <tbody><tr><td> <p class="caption"> Tabella <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2860.htm#almlanchor16126">691.9</a>. Elenco delle parole chiave che esprimono unit&#224; di misura data-orario. </p> <div class="object"> <table class="table" summary=""> <colgroup><col class="widthpixel243"><col class="widthpixel1031"></colgroup> <thead class="border"> <tr><td class="border">Parola chiave </td><td class="border">Significato </td></tr> </thead> <tbody class="border"> <tr><td class="border"> <pre>YEAR </pre> </td><td class="border">Anni </td></tr> <tr><td class="border"> <pre>MONTH </pre> </td><td class="border">Mesi </td></tr> <tr><td class="border"> <pre>DAY </pre> </td><td class="border">Giorni </td></tr> <tr><td class="border"> <pre>HOUR </pre> </td><td class="border">Ore </td></tr> <tr><td class="border"> <pre>MINUTE </pre> </td><td class="border">Minuti </td></tr> <tr><td class="border"> <pre>SECOND </pre> </td><td class="border">Secondi </td></tr> </tbody> </table> </div> </td></tr></tbody> </table> <p>Si osservino i due esempi seguenti:</p> <table summary="" id="almlanchor16127"> <tbody><tr><td> <div class="object"> <table class="object" summary=""> <tbody><tr><td> <pre>INTERVAL '12 HOUR 30 MINUTE 50 SECOND' INTERVAL '12:30:50' </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>Queste due forme rappresentano entrambe la stessa cosa: una durata di 12 ore, 30 minuti e 50 secondi. In generale, dovrebbe essere preferibile la seconda delle due forme di rappresentazione.</p> <table summary="" id="almlanchor16128"> <tbody><tr><td> <div class="object"> <table class="object" summary=""> <tbody><tr><td> <pre>INTERVAL '10 DAY 12 HOUR 30 MINUTE 50 SECOND' INTERVAL '10 DAY 12:30:50' </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>Come prima, i due esempi che si vedono sopra sono equivalenti. Intuitivamente, si pu&#242; osservare che non ci pu&#242; essere un altro modo di esprimere una durata in giorni, senza specificarlo attraverso la parola chiave <samp>DAY</samp>.</p> <p>Per completare la serie di esempi, si aggiungono anche i casi in cui si rappresentano esplicitamente quantit&#224; molto grandi, che di conseguenza sono approssimate al mese (come richiede lo standard <a name="almlindex19120"></a>SQL92):</p> <table summary="" id="almlanchor16129"> <tbody><tr><td> <div class="object"> <table class="object" summary=""> <tbody><tr><td> <pre>INTERVAL '10 YEAR 11 MONTH' INTERVAL '10 YEAR' </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>Gli intervalli di tempo possono servire per indicare un tempo trascorso rispetto al momento attuale. Per specificare espressamente questo fatto, si indica l'intervallo come un valore negativo, aggiungendo all'inizio un trattino (il segno meno).</p> <table summary="" id="almlanchor16130"> <tbody><tr><td> <div class="object"> <table class="object" summary=""> <tbody><tr><td> <pre>INTERVAL '- 10 YEAR 11 MONTH' </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>L'esempio che si vede sopra, esprime precisamente 10 anni e 11 mesi fa.</p> <h2>691.2 &nbsp; <a name="almltitle6073"></a><a name="almlanchor16131"></a> Operatori, funzioni ed espressioni </h2> <p><a name="almlindex19121"></a>SQL, pur non essendo un linguaggio di programmazione completo, mette a disposizione una serie di operatori e di funzioni utili per la realizzazione di espressioni di vario tipo.</p> <h3>691.2.1 &nbsp; <a name="almltitle6074"></a><a name="almlanchor16132"></a> Operatori aritmetici </h3> <p>Gli operatori che intervengono su valori numerici sono elencati nella tabella <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2860.htm#almlanchor16133">691.14</a>.</p> <table summary="" id="almlanchor16133"> <tbody><tr><td> <p class="caption"> Tabella <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2860.htm#almlanchor16133">691.14</a>. Elenco degli operatori aritmetici. </p> <div class="object"> <table class="table" summary=""> <colgroup><col class="widthpixel243"><col class="widthpixel1031"></colgroup> <thead class="border"> <tr><td class="border">Operatore e<br> operandi </td><td class="border">Descrizione </td></tr> </thead> <tbody class="border"> <tr><td class="border"> <pre>-<var>op</var> </pre> </td><td class="border">Inverte il segno dell'operando. </td></tr> <tr><td class="border"> <pre><var>op1</var> + <var>op2</var> </pre> </td><td class="border">Somma i due operandi. </td></tr> <tr><td class="border"> <pre><var>op1</var> - <var>op2</var> </pre> </td><td class="border">Sottrae dal primo il secondo operando. </td></tr> <tr><td class="border"> <pre><var>op1</var> * <var>op2</var> </pre> </td><td class="border">Moltiplica i due operandi. </td></tr> <tr><td class="border"> <pre><var>op1</var> / <var>op2</var> </pre> </td><td class="border">Divide il primo operando per il secondo. </td></tr> <tr><td class="border"> <pre><var>op1</var> % <var>op2</var> </pre> </td><td class="border">Modulo: il resto della divisione tra il primo e il secondo operando. </td></tr> </tbody> </table> </div> </td></tr></tbody> </table> <p>Nelle espressioni, tutti i tipi numerici esatti e approssimati possono essere usati senza limitazioni. Dove necessario, il sistema provvede a eseguire le conversioni di tipo.</p> <h3>691.2.2 &nbsp; <a name="almltitle6075"></a><a name="almlanchor16134"></a> Operazioni con i valori data-orario e con intervalli di tempo </h3> <p>Le operazioni che si possono compiere utilizzando valori data-orario e valori che esprimono intervalli di tempo, hanno significato solo in alcune circostanze. La tabella <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2860.htm#almlanchor16135">691.15</a> elenca le operazioni possibili e il tipo di risultato che si ottiene in base al tipo di operatori utilizzato.</p> <table summary="" id="almlanchor16135"> <tbody><tr><td> <p class="caption"> Tabella <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2860.htm#almlanchor16135">691.15</a>. Operatori e operandi validi quando si utilizzano valori data-orario e valori che esprimono intervalli di tempo. </p> <div class="object"> <table class="table" summary=""> <colgroup><col class="widthpixel487"><col class="widthpixel787"></colgroup> <thead class="border"> <tr><td class="border">Operatore e operandi </td><td class="border">Risultato </td></tr> </thead> <tbody class="border"> <tr><td class="border"> <pre><var>data_orario</var> - <var>data_orario</var> </pre> </td><td class="border">Intervallo </td></tr> <tr><td class="border"> <pre><var>data_orario</var> + <var>intervallo</var> </pre> </td><td class="border">Data-orario </td></tr> <tr><td class="border"> <pre><var>data_orario</var> - <var>intervallo</var> </pre> </td><td class="border">Data-orario </td></tr> <tr><td class="border"> <pre><var>intervallo</var> + <var>data_orario</var> </pre> </td><td class="border">Data-orario </td></tr> <tr><td class="border"> <pre><var>intervallo</var> + <var>intervallo</var> </pre> </td><td class="border">Intervallo </td></tr> <tr><td class="border"> <pre><var>intervallo</var> - <var>intervallo</var> </pre> </td><td class="border">Intervallo </td></tr> <tr><td class="border"> <pre><var>intervallo</var> * <var>numerico</var> </pre> </td><td class="border">Intervallo </td></tr> <tr><td class="border"> <pre><var>intervallo</var> / <var>numerico</var> </pre> </td><td class="border">Intervallo </td></tr> <tr><td class="border"> <pre><var>numerico</var> * <var>intervallo</var> </pre> </td><td class="border">Intervallo </td></tr> </tbody> </table> </div> </td></tr></tbody> </table> <h3>691.2.3 &nbsp; <a name="almltitle6076"></a><a name="almlanchor16136"></a> Operatori di confronto e operatori logici </h3> <p>Gli operatori di confronto determinano la relazione tra due operandi. Il risultato dell'espressione composta da due operandi posti a confronto &#232; di tipo booleano: <em>Vero</em> o <em>Falso</em>. Gli operatori di confronto sono elencati nella tabella <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2860.htm#almlanchor16137">691.16</a>.</p> <table summary="" id="almlanchor16137"> <tbody><tr><td> <p class="caption"> Tabella <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2860.htm#almlanchor16137">691.16</a>. Elenco degli operatori di confronto. </p> <div class="object"> <table class="table" summary=""> <colgroup><col class="widthpixel243"><col class="widthpixel1031"></colgroup> <thead class="border"> <tr><td class="border">Operatore e<br> operandi </td><td class="border">Descrizione </td></tr> </thead> <tbody class="border"> <tr><td class="border"> <pre><var>op1</var> = <var>op2</var> </pre> </td><td class="border"><em>Vero</em> se gli operandi si equivalgono. </td></tr> <tr><td class="border"> <pre><var>op1</var> &lt;&gt; <var>op2</var> </pre> </td><td class="border"><em>Vero</em> se gli operandi sono differenti. </td></tr> <tr><td class="border"> <pre><var>op1</var> &lt; <var>op2</var> </pre> </td><td class="border"><em>Vero</em> se il primo operando &#232; minore del secondo. </td></tr> <tr><td class="border"> <pre><var>op1</var> &gt; <var>op2</var> </pre> </td><td class="border"><em>Vero</em> se il primo operando &#232; maggiore del secondo. </td></tr> <tr><td class="border"> <pre><var>op1</var> &lt;= <var>op2</var> </pre> </td><td class="border"><em>Vero</em> se il primo operando &#232; minore o uguale al secondo. </td></tr> <tr><td class="border"> <pre><var>op1</var> &gt;= <var>op2</var> </pre> </td><td class="border"><em>Vero</em> se il primo operando &#232; maggiore o uguale al secondo. </td></tr> </tbody> </table> </div> </td></tr></tbody> </table> <p>Quando si vogliono combinare assieme diverse espressioni logiche si utilizzano gli operatori logici. Come in tutti i linguaggi di programmazione, si possono usare le parentesi tonde per raggruppare le espressioni logiche in modo da chiarire l'ordine di risoluzione. Gli operatori logici sono elencati nella tabella <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2860.htm#almlanchor16138">691.17</a>.</p> <table summary="" id="almlanchor16138"> <tbody><tr><td> <p class="caption"> Tabella <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2860.htm#almlanchor16138">691.17</a>. Elenco degli operatori logici. </p> <div class="object"> <table class="table" summary=""> <colgroup><col class="widthpixel243"><col class="widthpixel1031"></colgroup> <thead class="border"> <tr><td class="border">Operatore e<br> operandi </td><td class="border">Descrizione </td></tr> </thead> <tbody class="border"> <tr><td class="border"> <pre>NOT <var>op</var> </pre> </td><td class="border">Inverte il risultato logico dell'operando. </td></tr> <tr><td class="border"> <pre><var>op1</var> AND <var>op2</var> </pre> </td><td class="border"><em>Vero</em> se entrambi gli operandi restituiscono il valore <em>Vero</em>. </td></tr> <tr><td class="border"> <pre><var>op1</var> OR <var>op2</var> </pre> </td><td class="border"><em>Vero</em> se almeno uno degli operandi restituisce il valore <em>Vero</em>. </td></tr> </tbody> </table> </div> </td></tr></tbody> </table> <p>Il meccanismo di confronto tra due operandi numerici &#232; evidente, mentre pu&#242; essere meno evidente con le stringhe di caratteri. Per la precisione, il confronto tra due stringhe avviene senza tenere conto degli spazi finali, per cui, le stringhe <samp>'ciao'</samp> e <samp>'ciao&nbsp;'</samp> dovrebbero risultare uguali attraverso il confronto di uguaglianza con l'operatore <samp>=</samp>.</p> <p>Con le stringhe, tuttavia, si possono eseguire dei confronti basati su modelli, attraverso gli operatori <samp>IS LIKE</samp> e <samp>IS NOT LIKE</samp>. Il modello pu&#242; contenere dei metacaratteri rappresentati dal trattino basso (<samp>_</samp>), che rappresenta un carattere qualsiasi, e dal simbolo di percentuale (<samp>%</samp>), che rappresenta una sequenza qualsiasi di caratteri. La tabella <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2860.htm#almlanchor16139">691.18</a> riassume quanto affermato.</p> <table summary="" id="almlanchor16139"> <tbody><tr><td> <p class="caption"> Tabella <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2860.htm#almlanchor16139">691.18</a>. Espressioni sulle stringhe di caratteri. </p> <div class="object"> <table class="table" summary=""> <colgroup><col class="widthpixel487"><col class="widthpixel787"></colgroup> <thead class="border"> <tr><td class="border">Espressioni e modelli </td><td class="border">Descrizione </td></tr> </thead> <tbody class="border"> <tr><td class="border"> <pre><var>stringa</var> IS LIKE <var>modello</var> </pre> </td><td class="border">Restituisce <em>Vero</em> se il modello corrisponde alla stringa. </td></tr> <tr><td class="border"> <pre><var>stringa</var> IS NOT LIKE <var>modello</var> </pre> </td><td class="border">Restituisce <em>Vero</em> se il modello non corrisponde alla stringa. </td></tr> <tr><td class="border"> <pre>_ </pre> </td><td class="border">Rappresenta un carattere qualsiasi. </td></tr> <tr><td class="border"> <pre>% </pre> </td><td class="border">Rappresenta una sequenza indeterminata di caratteri. </td></tr> </tbody> </table> </div> </td></tr></tbody> </table> <p>La presenza di valori indeterminati richiede la disponibilit&#224; di operatori di confronto in grado di determinarne l'esistenza. La tabella <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2860.htm#almlanchor16140">691.19</a> riassume gli operatori ammissibili in questi casi.</p> <table summary="" id="almlanchor16140"> <tbody><tr><td> <p class="caption"> Tabella <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2860.htm#almlanchor16140">691.19</a>. Espressioni di verifica dei valori indeterminati. </p> <div class="object"> <table class="table" summary=""> <colgroup><col class="widthpixel487"><col class="widthpixel787"></colgroup> <thead class="border"> <tr><td class="border">Operatori </td><td class="border">Descrizione </td></tr> </thead> <tbody class="border"> <tr><td class="border"> <pre><var>espressione</var> IS NULL </pre> </td><td class="border">Restituisce <em>Vero</em> se l'espressione genera un risultato indeterminato. </td></tr> <tr><td class="border"> <pre><var>espressione</var> IS NOT NULL </pre> </td><td class="border">Restituisce <em>Vero</em> se l'espressione non genera un risultato indeterminato. </td></tr> </tbody> </table> </div> </td></tr></tbody> </table> <p>Infine, occorre considerare una categoria particolare di espressioni che permettono di verificare l'appartenenza di un valore a un intervallo o a un elenco di valori. La tabella <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2860.htm#almlanchor16141">691.20</a> riassume gli operatori utilizzabili.</p> <table summary="" id="almlanchor16141"> <tbody><tr><td> <p class="caption"> Tabella <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2860.htm#almlanchor16141">691.20</a>. Espressioni per la verifica dell'appartenenza di un valore a un intervallo o a un elenco. </p> <div class="object"> <table class="table" summary=""> <colgroup><col class="widthpixel487"><col class="widthpixel787"></colgroup> <thead class="border"> <tr><td class="border">Operatori e operandi </td><td class="border">Descrizione </td></tr> </thead> <tbody class="border"> <tr><td class="border"> <pre><var>op1</var> IN (<var>elenco</var>) </pre> </td><td class="border"><em>Vero</em> se il primo operando &#232; contenuto nell'elenco. </td></tr> <tr><td class="border"> <pre><var>op1</var> NOT IN (<var>elenco</var>) </pre> </td><td class="border"><em>Vero</em> se il primo operando non &#232; contenuto nell'elenco. </td></tr> <tr><td class="border"> <pre><var>op1</var> BETWEEN <var>op2</var> AND <var>op3</var> </pre> </td><td class="border"><em>Vero</em> se il primo operando &#232; compreso tra il secondo e il terzo. </td></tr> <tr><td class="border"> <pre><var>op1</var> NOT BETWEEN <var>op2</var> AND <var>op3</var> </pre> </td><td class="border"><em>Vero</em> se il primo operando non &#232; compreso nell'intervallo. </td></tr> </tbody> </table> </div> </td></tr></tbody> </table> <h2>691.3 &nbsp; <a name="almltitle6077"></a><a name="almlanchor16142"></a> Le relazioni dal punto di vista di <a name="almlindex19122"></a>SQL </h2> <p><a name="almlindex19123"></a>SQL tratta le relazioni attraverso il modello tabellare; di conseguenza si adegua tutta la sua filosofia e il modo di esprimere i concetti nella sua documentazione. Pertanto, le relazioni per <a name="almlindex19124"></a>SQL sono delle &#171;tabelle&#187;, che vengono definite nel modo seguente dalla documentazione standard.</p> <ul> <li> <p>La tabella &#232; un insieme di pi&#249; righe. Una riga &#232; una sequenza non vuota di valori. Ogni riga della stessa tabella ha la stessa cardinalit&#224; e contiene un valore per ogni colonna di quella tabella. L'<var>i</var>-esimo valore di ogni riga di una tabella &#232; un valore dell'<var>i</var>-esima colonna di quella tabella. La riga &#232; l'elemento che costituisce la pi&#249; piccola unit&#224; di dati che pu&#242; essere inserita in una tabella e cancellata da una tabella.</p> </li> <li> <p>Il grado di una tabella &#232; il numero di colonne della stessa. In ogni momento, il grado della tabella &#232; lo stesso della cardinalit&#224; di ognuna delle sue righe; la cardinalit&#224; della tabella (cio&#232; il numero delle righe contenute) &#232; la stessa della cardinalit&#224; di ognuna delle sue colonne. Una tabella la cui cardinalit&#224; sia zero viene definita come vuota.</p> </li> </ul> <p>In pratica, la tabella &#232; un contenitore di informazioni organizzato in righe e colonne. La tabella viene identificata per nome, cos&#236; anche le colonne, mentre le righe vengono identificate attraverso il loro contenuto.</p> <p>Nel modello di <a name="almlindex19125"></a>SQL, le colonne sono ordinate, anche se ci&#242; non &#232; sempre un elemento indispensabile, dal momento che si possono identificare per nome. Inoltre sono ammissibili tabelle contenenti righe duplicate.</p> <table class="frame" summary=""> <tbody><tr><td> <p>Si osservi, comunque, che nel resto di questo documento si preferisce la terminologia generale delle basi&nbsp;di&nbsp;dati, dove, al posto di tabelle, righe e colonne, si parla piuttosto di relazioni, tuple e attributi.</p> </td></tr></tbody> </table> <h3>691.3.1 &nbsp; <a name="almltitle6078"></a><a name="almlanchor16143"></a> Creazione di una relazione <a name="almlindex19126"></a> </h3> <p>La creazione di una relazione avviene attraverso un'istruzione che pu&#242; assumere un'articolazione molto complessa, a seconda delle caratteristiche particolari che da questa relazione si vogliono ottenere. La sintassi pi&#249; semplice &#232; quella seguente:</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>CREATE TABLE <var>nome_relazione</var> ( <var>specifiche</var> ) </pre> </td></tr></tbody> </table> <p>Tuttavia, sono proprio le specifiche indicate tra le parentesi tonde che possono tradursi in un sistema molto confuso. La creazione di una relazione elementare pu&#242; essere espressa con la sintassi seguente:</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>CREATE TABLE <var>nome_relazione</var> (<var>nome_attributo</var> <var>tipo</var><strong class="syn">[</strong>,...<strong class="syn">]</strong>) </pre> </td></tr></tbody> </table> <p>In questo modo, all'interno delle parentesi vengono semplicemente elencati i nomi degli attributi seguiti dal tipo di dati che in essi possono essere contenuti. L'esempio seguente rappresenta l'istruzione necessaria a creare una relazione composta da cinque attributi, contenenti rispettivamente informazioni su: codice, cognome, nome, indirizzo e numero di telefono.</p> <table summary="" id="almlanchor16144"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>CREATE TABLE Indirizzi ( Codice integer, Cognome char(40), Nome char(40), Indirizzo varchar(60), Telefono varchar(40) ) </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <h3>691.3.2 &nbsp; <a name="almltitle6079"></a><a name="almlanchor16145"></a> Valori predefiniti </h3> <p>Quando si inseriscono delle tuple all'interno della relazione, in linea di principio &#232; possibile che i valori corrispondenti ad attributi particolari non siano inseriti esplicitamente. Se si verifica questa situazione (purch&#233; ci&#242; sia consentito dai vincoli), viene assegnato a questi elementi mancanti un valore predefinito. Questo pu&#242; essere stabilito all'interno delle specifiche di creazione della relazione; in mancanza di tale definizione, viene assegnato <samp>NULL</samp>, corrispondente al valore indefinito.</p> <p>La sintassi necessaria a creare una relazione contenente le indicazioni sui valori predefiniti da utilizzare &#232; la seguente:</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>CREATE TABLE <var>nome_relazione</var> ( <var>nome_attributo</var> <var>tipo</var> <strong class="syn">[</strong>DEFAULT <var>espressione</var><strong class="syn">]</strong> <strong class="syn">[</strong>,...<strong class="syn">]</strong> ) </pre> </td></tr></tbody> </table> <p>L'esempio seguente crea la stessa relazione gi&#224; vista nell'esempio precedente, specificando come valore predefinito per l'indirizzo, la stringa di caratteri: &#171;sconosciuto&#187;.</p> <table summary="" id="almlanchor16146"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>CREATE TABLE Indirizzi ( Codice integer, Cognome char(40), Nome char(40), Indirizzo varchar(60) DEFAULT 'sconosciuto', Telefono varchar(40) ) </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <h3>691.3.3 &nbsp; <a name="almltitle6080"></a><a name="almlanchor16147"></a> Vincoli interni alla relazione </h3> <p>Pu&#242; darsi che in certe situazioni, determinati valori all'interno di una tupla non siano ammissibili, a seconda del contesto a cui si riferisce la relazione. I vincoli interni alla relazione sono quelli che possono essere risolti senza conoscere informazioni esterne alla relazione stessa.</p> <p>Il vincolo pi&#249; semplice da esprimere &#232; quello di non ammissibilit&#224; dei valori indefiniti. La sintassi seguente ne mostra il modo.</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>CREATE TABLE <var>nome_relazione</var> ( <var>nome_attributo</var> <var>tipo</var> <strong class="syn">[</strong>NOT NULL<strong class="syn">]</strong> <strong class="syn">[</strong>,...<strong class="syn">]</strong> ) </pre> </td></tr></tbody> </table> <p>L'esempio seguente crea la stessa relazione gi&#224; vista negli esempi precedenti, specificando che il codice, il cognome, il nome e il telefono non possono essere indeterminati.</p> <table summary="" id="almlanchor16148"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>CREATE TABLE Indirizzi ( Codice integer NOT NULL, Cognome char(40) NOT NULL, Nome char(40) NOT NULL, Indirizzo varchar(60) DEFAULT 'sconosciuto', Telefono varchar(40) NOT NULL ) </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>Un altro vincolo importante &#232; quello che permette di definire che un gruppo di attributi deve rappresentare dati unici in ogni tupla, cio&#232; che non siano ammissibili tuple che per quel gruppo di attributi abbiano dati uguali. Segue lo schema sintattico relativo:</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>CREATE TABLE <var>nome_relazione</var> ( <var>nome_attributo</var> <var>tipo</var> <strong class="syn">[</strong>,...<strong class="syn">]</strong>, UNIQUE ( <var>nome_attributo</var><strong class="syn">[</strong>,...<strong class="syn">]</strong> ) <strong class="syn">[</strong>,...<strong class="syn">]</strong> ) </pre> </td></tr></tbody> </table> <p>L'indicazione dell'unicit&#224; pu&#242; riguardare pi&#249; gruppi di attributi in modo indipendente. Per ottenere questo si possono indicare pi&#249; opzioni <samp>UNIQUE</samp>.</p> <table class="frame" summary=""> <tbody><tr><td> <p>&#200; il caso di osservare che il vincolo <samp>UNIQUE</samp> non &#232; sufficiente per impedire che i dati possano essere indeterminati. Infatti, il valore indeterminato, <samp>NULL</samp>, &#232; diverso da ogni altro <samp>NULL</samp>.</p> </td></tr></tbody> </table> <p>L'esempio seguente crea la stessa relazione gi&#224; vista negli esempi precedenti, specificando che i dati dell'attributo del codice devono essere unici per ogni tupla.</p> <table summary="" id="almlanchor16149"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>CREATE TABLE Indirizzi ( Codice integer NOT NULL, Cognome char(40) NOT NULL, Nome char(40) NOT NULL, Indirizzo varchar(60) DEFAULT 'sconosciuto', Telefono varchar(40) NOT NULL, UNIQUE (Codice) ) </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <p>Quando un attributo, o un gruppo di attributi, costituisce un riferimento importante per identificare le varie tuple che compongono la relazione, si pu&#242; utilizzare il vincolo <samp>PRIMARY KEY</samp>, che pu&#242; essere utilizzato una sola volta. Questo vincolo stabilisce anche che i dati contenuti, oltre a non poter essere doppi, non possono essere indefiniti.</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>CREATE TABLE <var>nome_relazione</var> ( <var>nome_attributo</var> <var>tipo</var> <strong class="syn">[</strong>,...<strong class="syn">]</strong>, PRIMARY KEY ( <var>nome_attributo</var><strong class="syn">[</strong>,...<strong class="syn">]</strong> ) ) </pre> </td></tr></tbody> </table> <p>L'esempio seguente crea la stessa relazione gi&#224; vista negli esempi precedenti specificando che l'attributo del codice deve essere considerato come chiave primaria.</p> <table summary="" id="almlanchor16150"> <tbody><tr><td> <div class="object"> <table class="pre" summary=""> <tbody><tr><td> <pre>CREATE TABLE Indirizzi ( Codice integer, Cognome char(40) NOT NULL, Nome char(40) NOT NULL, Indirizzo varchar(60) DEFAULT 'sconosciuto', Telefono varchar(40) NOT NULL, PRIMARY KEY (Codice) ) </pre> </td></tr></tbody> </table> </div> </td></tr></tbody> </table> <h3>691.3.4 &nbsp; <a name="almltitle6081"></a><a name="almlanchor16151"></a> Vincoli esterni alla relazione </h3> <p>I vincoli esterni alla relazione riguardano principalmente la connessione con altre relazioni e la necessit&#224; che i riferimenti a queste siano validi. La definizione formale di questa connessione &#232; molto complessa e qui non viene descritta. Si tratta, in ogni caso, dell'opzione <samp>FOREIGN KEY</samp> seguita da <samp>REFERENCES</samp>.</p> <p>Vale la pena per&#242; di considerare i meccanismi che sono coinvolti. Infatti, nel momento in cui si inserisce un valore, il sistema pu&#242; impedire l'operazione perch&#233; non valida in base all'assenza di quel valore in un'altra relazione esterna specificata. Il problema nasce per&#242; nel momento in cui nella relazione esterna viene eliminata o modificata una tupla che &#232; oggetto di un riferimento da parte della prima. Si pongono le alternative seguenti.</p> <table summary="" id="almlanchor16152"> <tbody><tr><td> <div class="object"> <table class="table" summary=""> <colgroup><col class="widthpixel243"><col class="widthpixel1031"></colgroup> <thead class="border"> <tr><td class="border">Vincolo </td><td class="border">Descrizione </td></tr> </thead> <tbody class="border"> <tr><td class="border"> <pre>CASCADE </pre> </td><td class="border">Se nella relazione esterna il dato a cui si fa riferimento &#232; stato cambiato, viene cambiato anche il riferimento nella relazione di partenza; se nella relazione esterna la tupla corrispondente viene rimossa, viene rimossa anche la tupla della relazione di partenza. </td></tr> <tr><td class="border"> <pre>SET NULL </pre> </td><td class="border">Se viene a mancare l'oggetto a cui si fa riferimento, viene modificato il dato attribuendo il valore indefinito. </td></tr> <tr><td class="border"> <pre>SET DEFAULT </pre> </td><td class="border">Se viene a mancare l'oggetto a cui si fa riferimento, viene modificato il dato attribuendo il valore predefinito. </td></tr> <tr><td class="border"> <pre>NO ACTION </pre> </td><td class="border">Se viene a mancare l'oggetto a cui si fa riferimento, non viene modificato il dato contenuto nella relazione di partenza. </td></tr> </tbody> </table> </div> </td></tr></tbody> </table> <p>Le azioni da compiere si possono distinguere in base all'evento che ha causato la rottura del riferimento: cancellazione della tupla della relazione esterna o modifica del suo contenuto.</p> <h3>691.3.5 &nbsp; <a name="almltitle6082"></a><a name="almlanchor16153"></a> Modifica della struttura della relazione <a name="almlindex19127"></a> </h3> <p>La modifica della struttura di una relazione riguarda principalmente la sua organizzazione in attributi. Le cose pi&#249; semplici che si possono desiderare di fare sono l'aggiunta di nuovi attributi e l'eliminazione di attributi gi&#224; esistenti. Vedendo il problema in questa ottica, la sintassi si riduce ai due casi seguenti:</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>ALTER TABLE <var>nome_relazione</var> ADD <strong class="syn">[</strong>COLUMN<strong class="syn">]</strong> <var>nome_attributo</var> <var>tipo</var> <strong class="syn">[</strong><var>altre_caratteristiche</var><strong class="syn">]</strong> </pre> </td></tr></tbody> </table> <table class="syntax" summary=""> <tbody><tr><td> <pre>ALTER TABLE <var>nome_relazione</var> DROP <strong class="syn">[</strong>COLUMN<strong class="syn">]</strong> <var>nome_attributo</var> </pre> </td></tr></tbody> </table> <p>Nel primo caso si aggiunge un attributo, del quale si deve specificare il nome, il tipo ed eventualmente i vincoli; nel secondo si tratta solo di indicare l'attributo da eliminare. A livello di singolo attributo pu&#242; essere eliminato o assegnato un valore predefinito.</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>ALTER TABLE <var>nome_relazione</var> ALTER <strong class="syn">[</strong>COLUMN<strong class="syn">]</strong> <var>nome_attributo</var> DROP DEFAULT </pre> </td></tr></tbody> </table> <table class="syntax" summary=""> <tbody><tr><td> <pre>ALTER TABLE <var>nome_relazione</var> ALTER <strong class="syn">[</strong>COLUMN<strong class="syn">]</strong> <var>nome_attributo</var> SET DEFAULT <var>valore_predefinito</var> </pre> </td></tr></tbody> </table> <h3>691.3.6 &nbsp; <a name="almltitle6083"></a><a name="almlanchor16154"></a> Eliminazione di una relazione <a name="almlindex19128"></a> </h3> <p>L'eliminazione di una relazione, con tutto il suo contenuto, &#232; un'operazione semplice che dovrebbe essere autorizzata solo all'utente che l'ha creata.</p> <table class="syntax" summary=""> <tbody><tr><td> <pre>DROP TABLE <var>nome_relazione</var> </pre> </td></tr></tbody> </table> <hr> <p>Appunti di informatica libera 2008 --- <em>Copyright &#169; 2000-2008 Daniele Giacomini -- &lt;<em>appunti2&#8201;(ad)&#8201;gmail&#183;com</em>&gt;</em></p> <hr> <p>Dovrebbe essere possibile fare riferimento a questa pagina anche con il nome <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/linguaggio_sql_ddl.htm">linguaggio_sql_ddl.htm</a></p> <p> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2861.htm">[successivo]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2859.htm">[precedente]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a2.htm">[inizio]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a21088.htm">[fine]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a21.htm">[indice generale]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a22.htm">[indice ridotto]</a> <a href="file:///C:/Documents%20and%20Settings/Fabrizio/Desktop/SCUOLA%202008/Documentazione%20da%20internet/%28appunti%20di%20informatica%20libera%202008%29%20a2-2008.htm/a21088.htm">[indice analitico]</a> </p> <p class="validator"><a href="http://validator.w3.org/check/referer"><img src="SQL-DDL_files/v15445.png" alt="Valid ISO-HTML!"></a></p> <p class="validator"><a href="http://jigsaw.w3.org/css-validator/check/referer"><img src="SQL-DDL_files/vcss.png" alt="CSS validator!"></a></p> </body></html>
///(Fine file: SQL-DDL.htm)

///File: Regola-FunzioniAggregazione.txt
Le principali funzioni di aggregazione sono 5
: SUM, AVG, MIN, MAX, COUNT ______________________________________________________________________ Regola delle funzioni di aggregazione: ______________________________________ Se in una query compaiono, dopo la parola chiave SELECT, N campi, dei quali K raggruppati (K<N) si deve necessariamente raggruppare(GROUP BY) per i N-k campi rimanenti Es: SELECT a,b,c, SUM(d),AVG(e) // N == 5, K==2 FROM … WHERE … GROUP BY a,b,c // N-K == 3 (a,b,c) ______________ _________________________________________________________________________________ INOLTRE: Nella clausola WHERE NON vengono accettate funzioni di aggregazione: usare HAVING
///(Fine file: Regola-FunzioniAggregazione.txt)