ISTITUTO TECNICO INDUSTRIALE G. M. ANGIOY SASSARI PROGETTAZIONE DI DATABASE Microsft Transact SQL Lezione 21 Questa dispensa è rilasciata sotto la licenza Creative Common CC BY-NC-SA. Chiunque può copiare, distribuire, modificare, creare opere derivate dall'originale, ma non a scopi commerciali, a condizione che venga riconosciuta la paternità dell'opera all'autore e che alla nuova opera vengano attribuite le stesse licenze dell'originale. Versione del: 30/09/2014 Revisione numero: 3 Prof. Andrea Zoccheddu Dipartimento di Informatica Immagine di copertina da: http://www.iamsterdam.com/en-GB/living/education/Dutch-Education-System DIPARTIMENTO INFORMATICA E TELECOMUNICAZIONI Dispensa DB Dispensa 21 - MS T-SQL pag. 2 IL DIALETTO TRANSACT SQL DI MICROSOFT MICROSOFT SQL SERVER Il Prodotto MICROSOFT SQL SERVER Le dispense SQL descrivono un generico SQL utilizzato nella maggior parte dei database, noto come standard SQL92; tuttavia esistono delle varianti a questo linguaggio, generalmente indicate come «dialetti». Microsoft Sql Server è un ambiente di gestione di basi di dati (RDBMS) che ha proposto diverse versioni ed utilizza uno specifico dialetto non come T-SQL, ovvero Transact-SQL. In questa dispensa analizzeremo la sintassi del linguaggio T-SQL per creare, gestire e analizzare i database. Per saperne di più sul RDBMS e sul T-SQL è possibile consultare i seguenti link: technet.microsoft.com Guida di riferimento a Transact-SQL Versioni e distribuzioni di SQL Server Installazione per SQL Server 2012 http://technet.microsoft.com/it-it/library/bb500469.aspx http://technet.microsoft.com/it-it/library/bb510741(v=sql.110).aspx http://it.wikipedia.org/wiki/Microsoft_SQL_Server http://technet.microsoft.com/it-it/library/bb500469.aspx Le versioni di SQL Server sono state molte; traggo le principali da Wikipedia: anno 1993 1995 1996 1998 1999 2000 2003 2005 2008 2010 2012 Nome SQL Server 4.2 SQL Server 6.0 SQL Server 6.5 SQL Server 7.0 SQL Server 7.0 OLAP SQL Server 2000 32-bit SQL Server 2000 64-bit SQL Server 2005 (sia 32-bit che 64-bit) SQL Server 2008 (sia 32-bit che 64-bit) SQL Server 2008 R2 (sia 32-bit che 64-bit) SQL Server 2012 (sia 32-bit che 64-bit) in fase beta nome in codice SQL95 Hydra Sphinx Plato Shiloh Liberty Yukon Katmai Denali versione gratuita No No No No No No Si Express Express Express Il linguaggio TSQL che è affrontato in questa dispensa: Si riferisce alla versione SQL Server 2008 (sia 32-bit che 64-bit); È trattato in modo parziale e sintetico, tralasciando alcuni elementi troppo tecnici. DATA DESCRIPTION LANGUAGE Il DDL di TSQL permette i consueti comandi di gestione delle strutture del database (creazione, modifica, eliminazione) tra cui analizzeremo i seguenti: CREATE CREATE OR ALTER CREATE OR ALTER CREATE OR ALTER CREATE OR ALTER CREATE OR ALTER CREATE OR ALTER CREATE OR ALTER CREATE OR ALTER CREATE OR ALTER CREATE OR ALTER DATABASE TYPE TABLE INDEX VIEW TRIGGER PROCEDURE GROUP USER GRANT RULE Prof. Andrea Zoccheddu Serve per creare un nuovo database Serve per definire un nuovo tipo di dato Serve per definire una tabella dentro il database Serve per definire un indice di ricerca sui dati Serve per definire una vista (query con diritti) Serve per definire un meccanismo automatico sui dati Serve per definire una procedura strutturata e articolata Serve per definire un gruppo di utenti Serve per definire un utente Serve per definire i diritti di accesso ai dati Serve per definire un vincolo globale sul database ITI G. M. ANGIOY SASSARI Dispensa DB Dispensa 21 - MS T-SQL pag. 3 DATA MANIPULATION LANGUAGE Il DML di TSQL permette i consueti comandi di gestione dei dati contenuti nelle strutture del database, tra cui analizzeremo i seguenti: SELECT INSERT INTO DELETE UPDATE Serve per interrogare il database e ottenere informazioni calcolate Serve per inserire record nelle tabelle Serve per cancellare record dalle tabelle Serve per modificare alcuni campi di record esistenti nelle tabelle TSQL per Procedure e Trigger Oltre ai precedenti comandi, il DML di TSQL permette di scrivere il corpo delle procedure create con il consueto comando e prevede una sintassi specifica per elaborare i dati; analizzeremo la sintassi relativa a: VARIABILI IF WHILE PARAMETRI Dichiarazione di variabili e assegnazione di valori, con operazioni Serve per decidere l’esecuzione di blocchi in funzione di un controllo Serve per iterare l’esecuzione di blocchi in funzione di un controllo Servono per far comunicare la procedura con il chiamante TSQL per gestire stringhe e date Infine, oltre alle consuete funzioni previste dal SQL92, il DML di TSQL permette di usare funzioni per gestire dati che spesso sfuggono allo standard; analizzeremo la sintassi relativa a: STRINGHE DATE Funzioni per manipolare stringhe, compiere ricerche e produrre nuove stringhe Funzioni per ottenere date e orari dal sistema operativo, per gestire i formati di date/orari Creazione del database All’inizio c’era il nulla… e il database non esisteva ancora. Il verbo con cui costruirlo ricalca abbastanza la sintassi standard: CREATE DATABASE nome_database [ ON { [ PRIMARY ] [ <specificofile1> [ ,... specificofileK ] [ , <gruppofile1> [ ,... gruppofileH ] ] [ LOG ON { <specificofile1> [ ,... specificofileN ] } ] } ] [ COLLATE nome_raccolta ] [ WITH <opzioni_accesso_esterno> ] ]; Questo comando crea un nuovo database con un suo nome. Quando viene creato, il database è vuoto ma, in realtà, il motore del database server costruisce un insieme di tabelle di sistema (non visibili ad utenti generici) per predisporre un ambiente agevole: ad esempio alcuni preparano le tabelle per i contatori (i campi auto-incrementanti) o per gli utenti e i diritti …; ai nostri fini è trascurabile sia l’analisi di queste tabelle, sia tutte le opzioni della sintassi TSQL: possiamo perciò limitarci alla sintassi più elementare (corretta) seguente: Esempio CREATE DATABASE Scuola; a Comandi Create Per avere l’elenco completo dei comandi CREATE http://technet.microsoft.com/it-it/library/cc879262.aspx di T-SQL è possibile consultare qui: Comandi Drop Per ogni comando Create di T-SQL esiste anche il suo antagonista DROP che serve per eliminare una struttura dal database. Per esempio DROP TABLE Biblioteca. Prof. Andrea Zoccheddu ITI G. M. ANGIOY SASSARI Dispensa DB Dispensa 21 - MS T-SQL pag. 4 Tipi di dato preesistenti Fonte (informazione tratta dal seguente sito) : http://msdn.microsoft.com/it-it/library/ms187752.aspx a Come tutti i linguaggi, anche TSQL dispone di tipi di dato pronti. Questi tipi servono per sapere cosa poter archiviare dentro le tabelle (numeri, testo, ecc…). I tipi sono: Tipo di dato bigint numeric bit smallint decimal smallmoney int tinyint money float real date datetimeoffset datetime2 smalldatetime datetime time char (n) varchar (n) text nchar (n) nvarchar (n) ntext binary varbinary image cursor timestamp hierarchyid uniqueidentifier sql_variant Xml Table Categoria Numerici esatti Numerici esatti Numerici esatti Numerici esatti Numerici esatti Numerici esatti Numerici esatti Numerici esatti Numerici esatti Ampiezza Descrizione 8 byte ± 9 mld di mld circa 2 byte usare per vero/falso, on/off ± 32.000 circa 4 byte 1 byte ± 2 mld circa da 0 a 255 Numerici approssimati Numerici approssimati K byte 4 byte Esempio accessi al sito web si/no pagine di un libro temperatura febbre prezzo di un oggetto età umana bilancio di una società programma scientifico programma scientifico da 01-01-0001 a 31-12-9999 giorno storico Tempo Tempo Da 1 gennaio 1 D.C. al 31 dicembre 9999 D.C., 23:59:59.9999999 Tempo Data come Date, Orari come Time Tempo da 1 gennaio 1900 a 6 giugno 2079, Tempo da 1/1/1753 a 31/12/ 9999, orari da 00:00:00.000 a 23:59:59.997 Tempo da 00.00.00.0000000 a 23.59.59.9999999 (decimilionesimo sec) Stringhe di caratteri n byte n ≤ 1800 Stringhe di caratteri max n byte n ≤ 1800 Stringhe di caratteri 2.147.483.647 byte Non unicode Stringhe Unicode n byte n ≤ 1800 Stringhe Unicode max n byte n ≤ 1800 Stringhe Unicode 2.147.483.647 byte Non unicode Stringhe binarie Stringhe binarie Stringhe binarie Altri tipi di dati Altri tipi di dati Altri tipi di dati Altri tipi di dati Altri tipi di dati Altri tipi di dati Altri tipi di dati scadenza prestito momento ingresso docente orario ingresso codice fiscale nome di persona descrizione di un film codice fiscale nome di persona descrizione di un film Video video foto speciale momento molto preciso ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ file xml Con il simbolo ♥ si mettono in evidenza i tipi usati più di frequente. Nuovi Tipi di dato In un sistema per database compatibile con lo standard è possibile definire nuovi tipi di dato idonei per informazioni particolari. Nel modello logico relazionale le tabelle si chiamano Relazioni e i valori ammissibili nei campi sono detti Domini. Create Type Per definire un nuovo tipo di dato occorre specificare il suo Nome, il tipo di partenza da cui ottenerlo e una condizione per verificare il requisito a cui il tipo deve rispondere. La sintassi è la seguente: Prof. Andrea Zoccheddu ITI G. M. ANGIOY SASSARI Dispensa DB Dispensa 21 - MS T-SQL pag. 5 CREATE TYPE [ schema_name. ] type_name FROM base_type [ ( precision [ , scale ] ) ] [ NULL | NOT NULL ] | EXTERNAL NAME assembly_name [ .class_name ] | AS TABLE ( { <column_definition> | <computed_column_definition> } [ <table_constraint> ] [ ,...n ] ) ; Vediamo un esempio pratico del suo uso: ESEMPIO 1. (CREATE TYPE) CREATE TYPE Scuola.Piano FROM CHAR (1) NOT NULL AS TABLE (CONSTRAINT CHECK (Value = "T" OR Value BETWEEN "1" AND "5" ) ) ; il tipo Piano è una stringa di un carattere obbligatorio che coincide con la lettera T oppure con il carattere che rappresenta una cifra compresa tra 1 e 5. CREATE TYPE Scuola.Indirizzo FROM CHAR (11) NOT NULL AS TABLE (CONSTRAINT CHECK (Value IN ("Biennio", "Chimica", "Elettronica", "Informatica", "Meccanica") ) ) ; il tipo Indirizzo è una stringa di 11 caratteri obbligatori che sia incluso tra quelli specificati. CREATE TYPE Scuola.Sesso FROM CHAR(1) AS TABLE (CONSTRAINT CHECK (Value = "F" OR Value = "M") ) ; il tipo Sesso è una stringa di 1 carattere facoltativo, che sia F oppure M (oppure NULL). CREATE TYPE Scuola.TipoPrezzo FROM smallmoney AS TABLE (CONSTRAINT CHECK (Value > 0) ) ; il tipo TipoPrezzo è una moneta i cui elementi devono soddisfare la condizione di essere maggiori di zero (zero escluso, in questo caso). a Definizione di Tabelle Create Table La sintassi generale del comando è: CREATE TABLE [ database_name . [ schema_name ] . | schema_name . ] table_name [ AS FileTable ] ( { <column_definition> | <computed_column_definition> | <column_set_definition> | [ <table_constraint> ] [ ,...n ] } ) [ ON { partition_scheme_name ( partition_column_name ) | filegroup | "default" } ] [ { TEXTIMAGE_ON { filegroup | "default" } ] [ FILESTREAM_ON { partition_scheme_name | filegroup | "default" } ] [ WITH ( <table_option> [ ,...n ] ) ] [ ; ] La creazione delle tabelle è fondamentale per un database. Solitamente si devono costruire specificando anche chiavi primarie, esterne, vincoli interni ed esterni; ma è anche possibile modificare la struttura della tabella in seguito, variando campi e vincoli. L’opzione CONSTRAINT serve per specificare i vincoli sul campo oppure sull’intera tabella. Se la parola segue un campo significa che i vincoli sono riferiti al campo; se la parola è posta dopo la dichiarazione dei campi significa che i vincoli sono riferiti alla tabella. Chiavi Primarie e auto-incremento Il vincolo PRIMARY KEY è ammesso una sola volta in una tabella, ma può essere riferito a più attributi insieme (si sconsiglia comunque di usare PK su molti attributi, conviene dichiarare un contatore). Prof. Andrea Zoccheddu ITI G. M. ANGIOY SASSARI Dispensa DB Dispensa 21 - MS T-SQL pag. 6 ESEMPIO 2. (PRIMARY KEY) Il caso più semplice di tabella impone di indicare il suo nome e almeno un campo; non è obbligatorio indicare una chiave primaria (ovvero è sintatticamente corretto) ma è fortemente sconsigliato avere tabelle prive. L’esempio seguente definisce una tabelle per le aule della scuola, con una K, il corpo dove si trova (es. nel corpo H), il piano (es. piano 2), il numero dell’aula (es. 7) e i metri quadri. Il vincolo NOT NULL impone l’obbligatorietà di un valore. CREATE TABLE Scuola.Aule ( IDAula CHAR (4) NOT NULL CONSTRAINT PRIMARY KEY , Corpo CHAR (1) NOT NULL , Piano CHAR (1) NOT NULL , Numero CHAR (2) NOT NULL , Mq DECIMAL (4,2) ); La chiave primaria può essere di qualsiasi tipo ma, spesso, si preferisce usare il tipo intero col vincolo IDENTITY che indica un contatore (auto incremento) che può avere anche due argomenti: il primo è il valore di partenza; il secondo è il passo di incremento. L’esempio seguente impone una chiave primaria numerica contatore, che parte da 1 ed avanza di +1 ad ogni nuovo inserimento. ESEMPIO 3. (PRIMARY KEY IDENTITY) CREATE TABLE Scuola.Aule ( IDAula INT IDENTITY (1, 1) NOT NULL CONSTRAINT PRIMARY KEY , Corpo CHAR (1) NOT NULL , Piano CHAR (1) NOT NULL , Numero CHAR (2) NOT NULL , Mq DECIMAL (4,2) ); ma una versione equivalente è la seguente: CREATE TABLE Scuola.Aule ( IDAula INT IDENTITY (1, 1) NOT NULL , Corpo CHAR (1) NOT NULL , Piano CHAR (1) NOT NULL , Numero CHAR (2) NOT NULL , Mq DECIMAL (4,2) , CONSTRAINT IDAula PRIMARY KEY , ); Chiavi Primarie su più campi È possibile anche specificare il vicolo CONSTRAINT alla fine, dopo la dichiarazione dei campi; in tal caso è possibile esprimere vincoli su più campi insieme e, per esempio, imporre una chiave primaria su più campi oppure una chiave esterna su più campi. Per esempio: ESEMPIO 4. (PRIMARY KEY SU PIÙ CAMPI) CREATE TABLE Scuola.Classi ( Anno CHAR (1) NOT NULL , Sezione CHAR (1) NOT NULL CONSTRAINT CHECK (Value BETWEEN "A" AND "Z") , Indirizzo CHAR (1) NOT NULL CONSTRAINT CHECK (Value IN ("BIE","CHI","ELE","INF","MEC") , CONSTRAINT CHECK Anno IN ('1' , '2', '3' , '4' , '5') , PRIMARY KEY (Anno, Sezione, Indirizzo) , FOREIGN KEY Aula REFERENCES Aule (Codice) ); Indice univoco Se occorre imporre che altri campi siano unici (e magari anche obbligatori diventando così delle chiavi candidate) è possibile usare il vincolo UNIQUE. Il vincolo si può usare su un solo campo o su un gruppo di campi. Prof. Andrea Zoccheddu ITI G. M. ANGIOY SASSARI Dispensa DB Dispensa 21 - MS T-SQL pag. 7 ESEMPIO 5. (UNIQUE) CREATE TABLE Scuola.Aule ( IDAula INT IDENTITY (1, 1) NOT NULL CONSTRAINT PRIMARY KEY , Corpo CHAR (1) NOT NULL UNIQUE , Piano CHAR (1) NOT NULL UNIQUE , Numero CHAR (2) NOT NULL UNIQUE , Mq DECIMAL (4,2) ); ma non funzionerebbe bene, poiché questo vincolo impedisce di avere più aule nello stesso corpo, impedisce di avere più aule con lo stesso piano, e più aule con stesso numero; tuttavia è possibile più sensatamente scrivere così: CREATE TABLE Scuola.Aule ( IDAula INT IDENTITY (1, 1) NOT NULL CONSTRAINT PRIMARY KEY , Corpo CHAR (1) NOT NULL , Piano CHAR (1) NOT NULL , Numero CHAR (2) NOT NULL , Mq DECIMAL (4,2) , CONSTRAINT UNIQUE (Corpo, Piano, Numero) ); l’ultimo esempio impedisce di duplicare la tripla (Corpo, Piano, Numero) e quindi impedisce che esistano due aule nello stesso corpo, allo stesso piano e con lo stesso numero; permette comunque di avere due aule allo stesso corpo e piano ma con diverso numero, o stesso piano e numero, ma diverso corpo e così via. Chiavi Esterne Il vincolo FOREIGN KEY è riferito ad un campo, ma può essere riferito a più attributi insieme (si sconsiglia) ed è sempre seguito dal riferimento alla tabella ed al campo correlato (solitamente una chiave primaria). Il vincolo FOREIGN KEY serve per imporre su un campo (o su un gruppo di campi) il vincolo di integrità referenziale ovvero la verifica che il valore sia presente in un campo di un’altra tabella correlata. ESEMPIO 6. (FOREIGN KEY) CREATE TABLE Scuola.Classi ( IDClasse INT IDENTITY (1, 1) NOT NULL PRIMARY KEY , Anno CHAR (1) NOT NULL Sezione CHAR (1) NOT NULL Indirizzo CHAR (1) NOT NULL CONSTRAINT UNIQUE (Anno, Sezione, Indirizzo) ); CREATE TABLE Scuola.Studenti ( IDStudente INT IDENTITY (1, 1) NOT NULL PRIMARY KEY , Cognome VARCHAR (250) NOT NULL , Nome VARCHAR (250) NOT NULL , Classe INT NOT NULL CONSTRAINT FOREIGN KEY REFERENCES Scuola.Classi(IDClasse) ); Chiavi Esterne su più campi ESEMPIO 7. (FOREIGN KEY) CREATE TABLE Scuola.Aule ( IDAula INT IDENTITY (1, 1) , AnnoCorso CHAR(1) NOT NULL, SezioneCorso CHAR(1) NOT NULL, IndirizzoCorso CHAR(3) NOT NULL, CONSTRAINT PRIMARY KEY (IDAula) , FOREIGN KEY (AnnoCorso, SezioneCorso, IndirizzoCorso) REFERENCES Classi (Anno, Sezione, Indirizzo), ); Prof. Andrea Zoccheddu ITI G. M. ANGIOY SASSARI Dispensa DB Dispensa 21 - MS T-SQL pag. 8 Controlli (check) Il vincolo CHECK serve per compiere un controllo come la verifica se il valore è uguale ad un certo valore, oppure è compreso in un intervallo o in un elenco. ESEMPIO 8. (CHECK) CREATE TABLE Scuola.Aule ( IDAula INT IDENTITY (1, 1) NOT NULL CONSTRAINT PRIMARY KEY , Piano CHAR (1) NOT NULL CONSTRAINT CHECK (Value IN ("T","1","2","3","4","5"), Mq DECIMAL (4,2) NOT NULL CONSTRAINT CHECK (Value > 0) DEFAULT 16.0 ); CREATE TABLE Scuola.Classi ( IDClasse INT IDENTITY (1, 1) NOT NULL PRIMARY KEY , IDAula INT NOT NULL CONSTRAINT FOREIGN KEY REFERENCES Scuola.Aule(IDAula) Anno CHAR (1) NOT NULL CONSTRAINT CHECK (Value IN ("1","2","3","4","5"), Sezione CHAR (1) NOT NULL CONSTRAINT CHECK (Value BETWEEN "A" AND "Z") , Indirizzo CHAR (1) NOT NULL CONSTRAINT CHECK (Value IN ("BIE","CHI","ELE","INF","MEC"), CONSTRAINT UNIQUE (Anno, Sezione, Indirizzo) ); CREATE TABLE Scuola.Studenti ( IDStudente INT IDENTITY (1, 1) NOT NULL PRIMARY KEY , Cognome VARCHAR (250) NOT NULL , Nome VARCHAR (250) NOT NULL , Sesso VARCHAR (5) NOT NULL , CAP VARCHAR (5) NOT NULL , Città VARCHAR (250) NOT NULL , Indirizzo VARCHAR (250) NOT NULL , Telefono VARCHAR (15) , Email VARCHAR (150), Classe INT NOT NULL CONSTRAINT FOREIGN KEY REFERENCES Scuola.Classi(IDClasse) ); CREATE TABLE Scuola.Prestiti ( IDPrestiti INT IDENTITY (1, 1) NOT NULL PRIMARY KEY , Richiedente CHAR(25) NOT NULL, Libro CHAR(25) NOT NULL, Data DATE DEFAULT Day(Now()) NOT NULL, Scadenza DATE NOT NULL, Restituito DATE, Cauzione DECIMAL(5,2) DEFAULT 10.75, CONSTRAINT CHECK Scadenza > Data, CHECK Restituito > Data, CHECK Cauzione >= 0 ); Tabelle ed Integrità Referenziale Chi ha studiato l’integrità referenziale ricorderà che essa obbliga i campi di una tabella (detta secondaria) ai campi di un’altra tabella (detta primaria) e spesso alle sue chiavi primarie. Questo vincolo può essere violato quando si cancellano dei record nella tabella primaria o si modificano i valori dei campi a cui fanno riferimento altre tabelle. Nella dichiarazione di tabella è possibile allora esplicitare le contromisure da adottare in questi casi. Vediamo le possibili sintassi: ESEMPIO 9. CREATE TABLE Tabella ( Campo Tipo vincolo, CONSTRAINT FOREIGN KEY (campo) REFERENCES Tabella2 (chiave) ON DELETE NO ACTION | CASCADE | SET NULL | SET DEFAULT ON UPDATE NO ACTION | CASCADE | SET NULL | SET DEFAULT ); Prof. Andrea Zoccheddu ITI G. M. ANGIOY SASSARI Dispensa DB Dispensa 21 - MS T-SQL pag. 9 dopo aver specificato la chiave esterna è possibile indicare uno o due clausole di reazione: • ON DELETE, che viene attivata nel caso sia cancellata una riga dalla tabella primaria • ON UPDATE, che viene attivata nel caso sia modificato il valore della chiave primaria in una riga della tabella primaria Per ciascuna di queste due clausole è possibile scegliere uno tra tre possibili eventi: • NO ACTION, significa che il comando è vietato e quindi la cancellazione o la modifica nella tabella primaria non deve avere effetti. È l’evento di default. • CASCADE, significa che le righe della tabella secondaria subiscono la stessa sorte di quelle della tabella primaria (ovvero sono a loro volta cancellate o modificate) • SET NULL, significa che nel campo chiave esterna delle righe correlate si impone il valore nullo. Questa opzione è ammissibile solo se la chiave esterna non sia obbligatoria (not null), altrimenti equivale a Non ACTION. • SET DEFAULT, significa che nel campo chiave esterna delle righe correlate si impone il valore di base, indicato dalla CREATE TABLE. ESEMPIO 10. CREATE TABLE VERIFICHE ( Studente CHAR[7] NOT NULL, Materia CHAR[12] DEFAULT Cinese, Data DATE NOT NULL, CONSTRAINT FOREIGN KEY (Studente) REFERENCES Studenti (Matricola) ON DELETE NO ACTION ON UPDATE CASCADE FOREIGN KEY (Materia) REFERENCES Discipline (Codice) ON DELETE SET DEFAULT ON UPDATE SET NULL ); Questo esempio impone che: • nel caso si tenti di cancellare uno studente ma siano presenti delle verifiche in questa tabella, allora viene impedita la cancellazione dello studente; • nel caso si tenti di modificare la matricola di uno studente e siano presenti delle verifiche, allora queste ultime modificano la chiave esterna ed assumono la nuova indicata per lo studente; • nel caso si tenti di cancellare una materia ma siano presenti delle rispettive verifiche in questa tabella, allora si sostituisce la materia con Cinese; • nel caso si tenti di modificare il codice della materia e siano presenti delle verifiche, allora queste ultime modificano la chiave esterna col valore nullo. Create Index Un indice è un supporto per compiere ricerche più veloci su una tabella ed eventualmente effettuare controlli associati. La sintassi generale (che tuttavia NON è prevista dallo standard SQL92) è la seguente: CREATE UNIQUE INDEX Nome-Indice ON Nome-Tabella (campo1 ASC/DESC , campo2 ASC/DESC , ...) Con le seguenti regole: • La parola UNIQUE è opzionale. Se è indicata allora i valori dei campi non possono essere duplicati, altrimenti (se omessa) è possibile duplicarli. Si noti che in caso di molti campi allora la duplicazione si intende per la coppia o terna o n-pla. • Il nome dell’indice è necessario perché serve per identificare l’indice nel database. Di solito si sceglie un nome distinto da altri oggetti del database. • L’indice è associato ad una sola tabella. Alla stessa tabella è possibile associare molti indici diversi. I vincoli CONSTRAINT della creazione di tabella creano automaticamente degli indici. Prof. Andrea Zoccheddu ITI G. M. ANGIOY SASSARI Dispensa DB Dispensa 21 - MS T-SQL • pag. 10 L’indice può essere creato su un solo nome di campo oppure su molti nomi di campo. In un caso si valuta il singolo valore, nell’altro si crea un indice su coppie, triple, ennuple. Ogni campo dell’indice è ordinato in modo crescente (ASC) o decrescente (DESC). ESEMPIO 11. INDICE SU UN CAMPO CREATE INDEX Studenti_NDX ON Studenti (Cognome ASC , Nome ASC) Questo indice permette di effettuare ricerche più veloci sui campi cognome e nome degli alunni, come in effetti accade spesso… ESEMPIO 12. INDICE SU PIÙ CAMPI CREATE UNIQUE INDEX Verifiche_NDX ON Interrogazioni (Alunno, Materia, Data) Questo indice permette di evitare che un alunno sia interrogato due volte nella stessa materia nello stesso giorno. Poiché non è specificato l’ordinamento è sottinteso che sia crescente (ASCendente). Opzioni SQL In alcuni dialetti SQL è possibile aggiungere all'indice alcuni vincoli per mezzo della clausola WITH, secondo la seguente sintassi: CREATE UNIQUE INDEX Nome-Indice ON Nome-Tabella (campo1 ASC/DESC , campo2 campo1 ASC/DESC , ...) WITH PRIMARY KEY || DISALLOW NULL || IGNORE NULL • La parola chiave WITH può essere omessa con tutto quello che segue. Se specificata serve per impostare un vincolo sull’indice. I vincoli possibili sono tre ma se ne può scegliere solo uno. • PRIMARY KEY vieta l’esistenza di valori nulli nei campi della tabella e sottintende l’opzione UNIQUE • DISALLOW NULL vieta i valori nulli, ma può essere usato senza UNIQUE e rende il campo della tabella obbligatorio • IGNORE NULL non vieta i valori nulli, e permette di costruire un indice generico Eliminare un indice In SQL è possibile eliminare l'indice dal database quando non serve più. Il comando ha seguente sintassi: DROP INDEX Nome-Indice Che elimina l’indice specificato dal suo nome. Create View Una Vista è una tabella dinamica analoga ad una query ma che costituisce un elemento autonomo con propri diritti, protezioni e vantaggi. In effetti una vista è calcolata attraverso l’esecuzione di una query ed il risultato costituisce però una vera e propria tabella. La sintassi generale della vista è la seguente: CREATE VIEW NomeVista (col1 , col2, ...) AS ( SELECT ... ); dove il numero di colonne della vista dovrebbe coincidere col numero di colonne della query. Prof. Andrea Zoccheddu ITI G. M. ANGIOY SASSARI Dispensa DB Dispensa 21 - MS T-SQL pag. 11 ESEMPIO 13. CREATE VIEW Maggiorenni (Matricola, Cognome, Nome, Età) AS ( SELECT Matricola, Cognome, Nome, Età FROM STUDENTI WHERE Età >= 18 ); questa vista crea una tabella coi dati degli studenti maggiorenni. Perché usare una vista? Il primo motivo per creare una vista è per mettere a disposizione di determinati utenti solo alcuni dati e non una intera tabella di dati. Per esempio un docente potrebbe avere accesso ai dati dei soli studenti delle classi in cui insegna ma non a quelli dell’intera scuola. In effetti alla vista possono essere associati dei diritti che permettono o impediscono l’accesso a determinati utenti o gruppi di utenti. In tali dati inoltre è possibile effettuare anche operazioni (inserimenti, modifiche e cancellazioni) purché in particolari condizioni e disponendo dei necessari diritti. Per esempio le query di Access sono in effetti delle viste. Altro motivo è che la vista può essere impiegata in una clausola FROM di una ulteriore query, come se fosse una tabella a tutti gli effetti. Questo è utile se il linguaggio non ammette subquery nella clausola FROM. Create Trigger Il Trigger (letteralmente grilletto, innesco) serve per definire un meccanismo automatico sui dati. Quando una determinata operazione viene effettuata sui dati il sistema verifica se esiste un trigger associato e lo esegue. Questo meccanismo serve per garantire che le operazioni sui dati siano eseguite correttamente, magari correggendo o completando l’operazione richiesta. Purtroppo anche questo comando non è nello standard SQL92, sebbene sia ampiamente implementato in numerosi motori per database. La sintassi del comando è la seguente: CREATE TRIGGER NomeTrigger [ BEFORE | AFTER ] ON Tabella FOR DELETE | INSERT | UPDATE EXECUTE Comandi //vedi procedure END; le due opzioni BEFORE e AFTER sono alternative (se ne usa una e solo una) : • AFTER, si usa nel caso di voler effettuare delle azioni prima che i controlli sui vincoli della tabella siano stati controllati. È utile per impostare valori di chiave primaria calcolati o per riempire dei campi lasciati vuoti prima che siano effettuati i normali controlli; • BEFORE, si usa per effettuare azioni dopo che i controlli sono stati superati (e nel caso che l’operazione abbia avuto successo), magari per modificare altre tabelle collegate o per modificare alcuni valori di alcuni campi. mentre le opzioni DELETE | INSERT | UPDATE sono facoltative (se ne usa una o due o tre) ed indicano il tipo di operazione che invoca l’esecuzione dei comandi. Create Rule L’asserzione è un vincolo articolato che può coinvolgere una, due o più tabelle e serve per garantire che le operazioni sui dati rispettino dei vincoli complessi. La sintassi del comando è la seguente: CREATE RULE NomeAsserzione CHECK (espressione); dove l’espressione deve essere booleana (vera o falsa) ed assume una forma analoga alle query annidate ovvero simili alle seguenti: Prof. Andrea Zoccheddu ITI G. M. ANGIOY SASSARI Dispensa DB Dispensa 21 - MS T-SQL • EXISTS (SELECT . . . . . . ) • Valore IN (SELECT . . . . . ) • (SELECT . . . ) OP (SELECT . . . ) pag. 12 ESEMPIO 14. La seguente asserzione: CREATE RULE CentoPerCento CHECK (NOT EXISTS ( SELECT SUM(Percentuale) FROM Composizione GROUP BY Prodotto HAVING SUM(Percentuale) > 100 ); ) esprime il fatto che non esiste alcun prodotto la cui composizione è formata da oltre il 100 % di ingredienti. LINGUAGGIO T-SQL E DICHIARAZIONI DI VARIABILI T-SQL variabili Fonte (informazione tratta dal seguente sito) : http://msdn.microsoft.com/it-it/library/ms188927.aspx Il linguaggio T-SQL dispone di variabili locali (che si possono usare sia in modo batch o all’interno di stored procedure in cui vengono dichiarate). Le variabili hanno tutte obbligatoriamente un tipo associato e devono essere dichiarate all’inizio del batch o della procedura in cui sono impiegate. Le variabili vengono dichiarate nel corpo di un batch o di una routine tramite l'istruzione DECLARE e i relativi valori vengono assegnati tramite un'istruzione SET o SELECT. È possibile dichiarare variabili di cursore con questa istruzione e utilizzarle insieme ad altre istruzioni correlate ai cursori. Dopo la dichiarazione, tutte le variabili vengono inizializzate con valore NULL, a meno che non venga fornito un valore nella dichiarazione. Definizione DECLARE @nomevar [, @nomevar2 tipo tipo2 [, …]] Esempio DECLARE @media decimal(5,2) , @conta integer , @nome char(50) a l’assegnazione di valori alle variabili può avvenire nei due seguenti modi: Definizione SET @nomevar = valore SELECT @nomevar = valore [, ….] Il primo modo consente una assegnazione di espressioni semplici, come nei classici comandi imperativi. Un comando SET può assegnare una sola variabile. Ciascun comando termina con un «a capo» senza punti e virgola né altri segni di fine comando. Per esempio: Esempio SET SET SET @media = 3.14 @conta = 0 @nome = "andrea" Il secondo modo consente una assegnazione del risultato di una query SQL. Una singola SELECT può assegnare molti valori ad altrettante variabili, separando con virgole le assegnazioni come avviene per la separazione dei campi di una ordinaria SELECT. Prof. Andrea Zoccheddu ITI G. M. ANGIOY SASSARI Dispensa DB Dispensa 21 - MS T-SQL pag. 13 Per esempio: Esempio SELECT @conta = COUNT(*), @media = AVG(Età) FROM Studenti WHERE Cognome = Nome ; SELECT @media = AVG(salario), @conta FROM Impiegati ; = COUNT(*) SELECT @nome = (Cognome + " " + Nome) FROM Studenti WHERE Matricola = "110893" ; L’assegnazione tramite SELECT deve essere opportunamente costruita in modo da garantire che qualsiasi esecuzione della SELECT produca esattamente un valore per ciascuna variabile. Se una SELECT produce più valori, la variabile riceve l’ultimo valore elaborato. Esempio SELECT @nome = (Cognome + " " + Nome) FROM Studenti WHERE Età > 17 ; È una query di assegnazione pericolosa poiché non è possibile stabilire in anticipo quale valore sarà assegnato alla variabile @nome. La variabile comunque riceve l’ultimo valore dell’elenco. Per arginare i difetti di una SELECT che rende molti valori potrebbe essere utile utilizzare un ordinamento e la scelta del solo primo elemento con l’operazione TOP 1. Esempio SELECT @nome = (Cognome + " " + Nome) TOP 1 FROM Studenti WHERE Età > 17 ORDER BY Cognome, Nome; Corregge la precedente query ordinando i valori e scegliendo il primo dell’elenco. Se una SELECT non produce alcun valore, allora la variabile mantiene il valore assunto in precedenza. Esempio SELECT @nome FROM Studenti WHERE false ; = "Apollo" È una query di assegnazione inutile, poiché la condizione è sempre falsa e la variabile @nome non riceverà il valore "Apollo". La variabile quindi conserva il valore che aveva in precedenza. Anche all’interno di un comando UPDATE è possibile assegnare valori a variabili: Esempio DECLARE @conta int SET @conta = 1 UPDATE Tabella SET @conta = Campo = @conta * 2 La variabile inizia da 1. La UPDATE esplora i record della Tabella e ad ogni record assegna il doppio del contatore; questo valore viene anche assegnato alla variabile che raddoppia ad ogni giro. In pratica assegna al Campo i valori 2, 4, 8, 16, 32, ecc … Prof. Andrea Zoccheddu ITI G. M. ANGIOY SASSARI Dispensa DB Dispensa 21 - MS T-SQL pag. 14 T-SQL variabili globali Fonte (informazione tratta dal seguente sito) : http://msdn.microsoft.com/it-it/library/ms187786.aspx Il linguaggio T-SQL non dispone di variabili globali ma possiede comunque delle funzioni di sistema connotate da una doppia @@ che precede il loro nome. Le funzioni di sistema riportate di seguito eseguono operazioni e restituiscono informazioni su valori, oggetti e impostazioni in SQL Server. Tra le funzioni di sistema possiamo ricordare: @@ERROR, @@IDENTITY, @@PACK_RECEIVED, @@ROWCOUNT, @@TRANCOUNT. T-SQL funzioni predefinite Fonte (informazione tratta dal seguente sito) : http://msdn.microsoft.com/it-it/library/ms174318.aspx SQL Server include numerose funzioni predefinite e consente inoltre di creare funzioni definite dall'utente. In questa pagina sono elencate le categorie delle funzioni predefinite. Funzione Funzioni per i set di righe Funzioni di aggregazione Funzioni di rango Funzioni scalari Descrizione Restituiscono un oggetto utilizzabile come i riferimenti a tabelle in un'istruzione SQL. Vengono applicate su una raccolta di valori e restituiscono un singolo valore di riepilogo. Restituiscono un valore di rango per ogni riga di una partizione. Vengono applicate a un singolo valore e restituiscono un singolo valore. È possibile utilizzare le funzioni scalari in tutte le posizioni in cui sono consentite espressioni. Funzioni scalari Categoria di funzioni Descrizione Funzioni di configurazione Restituiscono informazioni sulla configurazione corrente. Funzioni di conversione Supportano l'esecuzione del cast e la conversione del tipo di dati. Funzioni per i cursori Restituiscono informazioni sui cursori. Funzioni e tipi di dati di data Eseguono operazioni su valori di input di data e ora e restituiscono valori stringa, e ora numerici o di data e ora. Funzioni logiche Eseguono operazioni logiche. Funzioni matematiche Eseguono calcoli in base ai valori di input specificati come parametri per le funzioni e restituiscono valori numerici. Funzioni per i metadati Restituiscono informazioni sul database e sugli oggetti di database. Funzioni di sicurezza Restituiscono informazioni sugli utenti e sui ruoli. Funzioni per i valori stringa Eseguono operazioni su valori di input di tipo stringa (char o varchar) e restituiscono un valore stringa o numerico. Funzioni di sistema Eseguono operazioni e restituiscono informazioni su valori, oggetti e impostazioni in un'istanza di SQL Server. Funzioni statistiche di sistema Restituiscono informazioni statistiche sul sistema. Funzioni per i valori text e image Eseguono operazioni su valori di input o colonne di testo o immagini e restituiscono informazioni sul valore. Le funzioni predefinite scalari sono molto utili per gestire particolari tipi di dato. Prof. Andrea Zoccheddu ITI G. M. ANGIOY SASSARI Dispensa DB Dispensa 21 - MS T-SQL pag. 15 In particolare possiamo soffermarci sulle funzioni per i tipi data e ora, utili per confronti, differenze e orari di sistema. Tutti i valori di data e ora di sistema derivano dal sistema operativo del computer in cui è in esecuzione l'istanza di SQL Server. Le funzioni che ottengono valori della data e ora di sistema sono le seguenti: Funzione Sintassi Valore restituito Tipo reso SYSDATETIME SYSDATETIME () datetime2(7) SYSDATETIME OFFSET SYSDATETIMEO FFSET ( ) SYSUTC DATETIME SYSUTCDATETI ME ( ) CURRENT_ TIMESTAMP CURRENT_TIME STAMP GETDATE GETDATE ( ) GETUTCDATE GETUTCDATE ( ) DATENAME DAY DATENAME ( datepart ,date ) DATEPART ( datepart ,date ) DAY ( date ) MONTH MONTH ( date ) YEAR YEAR ( date ) DATEFROMPA RTS DATEFROMPAR TS ( year, month, day ) DATETIME2FRO MPARTS ( year, month, day,hour , minute, seconds, fracti ons, precision ) DATETIMEFRO MPARTS ( year, month, day, hou r,minute, seconds, milli seconds ) DATETIMEOFFS ETFROMPARTS ( year, month,day, hour , minute, seconds, fracti ons,hour_offset, minute _offset, precision ) SMALLDATETIM EFROMPARTS ( year, month,day, hour , minute ) TIMEFROMPART S ( hour, minute, seconds ,fractions, precision ) DATEDIFF ( datepart ,startdate , e nddate ) Restituisce il valore datetime2(7) che contiene la data e l'ora del computer in cui è in esecuzione l'istanza di SQL Server. La differenza di fuso orario non è inclusa. Restituisce il valore datetimeoffset(7) che contiene la data e l'ora del computer in cui è in esecuzione l'istanza di SQL Server. La differenza di fuso orario è inclusa. Restituisce il valore datetime2(7) che contiene la data e l'ora del computer in cui è in esecuzione l'istanza di SQL Server. La data e l'ora vengono restituite in formato ora UTC (Coordinated Universal Time). Restituisce il valore datetime che contiene la data e l'ora del computer in cui è in esecuzione l'istanza di SQL Server. La differenza di fuso orario non è inclusa. Restituisce il valore datetime che contiene la data e l'ora del computer in cui è in esecuzione l'istanza di SQL Server. La differenza di fuso orario non è inclusa. Restituisce il valore datetime che contiene la data e l'ora del computer in cui è in esecuzione l'istanza di SQL Server. La data e l'ora vengono restituite in formato ora UTC (Coordinated Universal Time). Restituisce una stringa di caratteri che rappresenta la datepart della data specificata. Restituisce un valore intero che rappresenta il valore datepart dell'argomentodate specificato. Restituisce un valore intero che rappresenta la parte del giorno della datespecificata. Restituisce un valore intero che rappresenta la parte mese di un valore datespecificato. Restituisce un valore intero che rappresenta la parte dell'anno di datespecificata. Restituisce un valore di tipo date per l'anno, il mese e il giorno specificati. Restituisce un valore datetime2 per la data e l'ora specificate e con la precisione indicata. datetime2 (precisi on ) Restituisce un valore di tipo datetimeper la data e l'ora specificate. datetime Restituisce un valore datetimeoffsetper la data e l'ora specificata e con gli offset e la precisione indicati. datetime (precisio n) Restituisce un valore di tiposmalldatetime per la data e l'ora specificate. smalldatetime Restituisce un valore time per l'ora specificate e con la precisione indicata. time (precision ) Restituisce il numero di limiti di datepart della data e ora che si sovrappongono tra due date specificate. int DATEPART DATETIME2 FROMPARTS DATETIME FROMPARTS DATETIMEOF FSET FROMPARTS SMALLDATETI ME FROMPARTS TIMEFROMPA RTS DATEDIFF datetimeoffset (7) datetime2(7) datetime datetime datetime nvarchar int int int int date Non è intenzione di questa dispensa analizzare in dettaglio l’intero panorama delle funzioni predefinite disponibili in SQL Server, per cui si rimanda alle pagine della guida in linea. Prof. Andrea Zoccheddu ITI G. M. ANGIOY SASSARI Dispensa DB Dispensa 21 - MS T-SQL pag. 16 COMANDI IMPERATIVI IN LINGUAGGIO T-SQL Fonte (informazione tratta dal seguente sito) : http://msdn.microsoft.com/it-it/library/ms174290.aspx Il linguaggio T-SQL dispone di comandi imperativi che permettono di dirigere il flusso di elaborazione per costruire programmi batch, funzioni o stored procedure. I comandi consentono di combinare i comandi tipici di SQL con quelli imperativi consueti ottenendo una notevole potenza elaborativa. COMANDO SEQUENZA (blocco di istruzioni) Il comando sequenza permette di racchiudere insieme gruppi di comandi per costruire un blocco unitario, come il BEGIN END del linguaggio Pascal e il blocco { … } dei linguaggi C-like (come C++, Java e C#). Definizione BEGIN . . . Elenco comandi . . . END Esempio BEGIN DECLARE @conta int SET @conta = 1 UPDATE Tabella SET @conta = Campo = @conta * 2 END COMANDO DECISIONALE (esecuzione condizionale) Il comando decisionale permette di decidere se eseguire o meno un comando, come lo IF THEN / ELSE del linguaggio Pascal e lo if () dei linguaggi C-like (come C++, Java e C#). Definizione IF ( condizione ) Elenco comandi ELSE Elenco comandi END Esempio DECLARE @quanti int SET @quanti = 0 SELECT @quanti = COUNT(*) FROM Versamenti WHERE IDsocio = @IDS AND IDprodotto = @IDP AND Data = "01/04/2014"; IF ( @quanti > 0 ) UPDATE Versamenti SET Quantità = Quantità + @quantità WHERE IDsocio = @IDS AND IDprodotto = @IDP AND Data = "01/04/2014"; ELSE INSERT INTO Versamenti VALUES ("01/04/2014", @IDS, @IDP, @quantità) Prof. Andrea Zoccheddu ITI G. M. ANGIOY SASSARI Dispensa DB Dispensa 21 - MS T-SQL pag. 17 COMANDO ITERATIVO (esecuzione ciclica) Il comando iterativo permette di ripetere l’esecuzione di comandi in un ciclo, come il WHILE del linguaggio Pascal e lo while () dei linguaggi C-like (come C++, Java e C#). Definizione WHILE (Condizione) { Comando | Sequenza | BREAK | CONTINUE } Condizione è l’espressione che restituisce TRUE o FALSE. Se l'espressione booleana include un'istruzione SELECT, tale istruzione deve essere racchiusa tra parentesi. Comando o Sequenza è una qualsiasi istruzione o un blocco di istruzioni Transact-SQL valide definite con un blocco di istruzioni. Per definire un blocco di istruzioni, utilizzare le parole chiave per il controllo di flusso BEGIN ed END. La parola chiave BREAK consente di uscire dal ciclo WHILE più interno. Vengono eseguite le istruzioni che si trovano dopo la parola chiave END, che segna la fine del ciclo. La parola chiave CONTINUE consente di ricominciare immediatamente il riavvio del ciclo WHILE (dalla condizione), ignorando tutte le istruzioni che seguono la parola chiave CONTINUE. Fonte (informazione tratta dal seguente sito) : http://msdn.microsoft.com/it-it/library/ms178642.aspx Esempio WHILE (SELECT AVG(ListPrice) FROM Production.Product) < $300 BEGIN UPDATE Production.Product SET ListPrice = ListPrice * 2 SELECT MAX(ListPrice) FROM Production.Product IF (SELECT MAX(ListPrice) FROM Production.Product) > $500 BREAK ELSE CONTINUE END PRINT 'Per il negozio è troppo costoso per rincarare ancora'; Nell'esempio precedente, se il prezzo medio di listino di un prodotto è minore di $300, il ciclo WHILE raddoppia i prezzi e quindi seleziona il prezzo massimo. Se il prezzo massimo è minore o uguale a $500, il ciclo WHILE viene riavviato e il prezzo viene nuovamente raddoppiato. Questo ciclo continua a raddoppiare i prezzi fino a quando il prezzo massimo non supera $500, quindi il ciclo WHILE viene terminato e viene stampato un messaggio. STORED PROCEDURE IN T-SQL Fonte (informazione tratta dal seguente sito) : http://msdn.microsoft.com/it-it/library/ms187926.aspx Sintassi generale Il comando CREATE PROCEDURE consente di creare una STORED PROCEDURE Transact-SQL o CLR (Common Language Runtime) in SQL Server. Le STORED PROCEDURE sono simili alle procedure di altri linguaggi di programmazione in quanto sono in grado di: Accettare parametri di input e restituire più valori sotto forma di parametri di output alla procedura o al batch che esegue la chiamata. Includere istruzioni di programmazione che eseguono le operazioni nel database, tra cui la chiamata di altre procedure. Restituire un valore di stato a una procedura o a un batch che esegue la chiamata per indicare l'esito positivo o negativo (e il motivo dell'esito negativo). Utilizzare questa istruzione per creare una stored procedure permanente nel database corrente o una stored procedure temporanea nel database tempdb. La sintassi della CREATE PROCEDURE è piuttosto ampia e complessa e lo studio di alcune sue parti esula dallo scopo di questa dispensa; pertanto procederemo ad un’analisi sommaria e parziale della sua struttura. Prof. Andrea Zoccheddu ITI G. M. ANGIOY SASSARI Dispensa DB Dispensa 21 - MS T-SQL pag. 18 Definizione --SQL Server Stored Procedure Syntax CREATE { PROC | PROCEDURE } [schema_name.] procedure_name [ { @parameter [ type_schema_name. ] data_type } [ VARYING ] [ = default ] [ OUT | OUTPUT | [READONLY] ] [ ,...n ] [ WITH <procedure_option> [ ,...n ] ] [ FOR REPLICATION ] AS { [ BEGIN ] sql_statement [;] [ ...n ] [ END ] } [;] <procedure_option> ::= [ ENCRYPTION ] [ RECOMPILE ] [ EXECUTE AS Clause ] La sintassi della CREATE PROCEDURE prevede le seguenti parti: L’intestazione inizia con CREATE PROCEDURE oppure con CREATE PROC seguito dal nome della procedura; il nome della procedura può essere preceduto dal nome dello schema (e da un punto); L’intestazione è seguita dall’elenco dei parametri, i cui nomi devono iniziare con la @ (l’elenco può essere racchiuso tra parentesi tonde, ma non è obbligatorio) Le opzioni WITH e FOR REPLICATION sono facoltative e per il momento le possiamo trascurare La parola chiave AS determina l’inizio del corpo della procedura; sebbene non obbligatorio è preferibile racchiudere il corpo con un blocco BEGIN END Vediamo di seguito alcuni esempi: Esempio CREATE PROCEDURE usp_add_kitchen @dept_id int, @kitchen_count int NOT NULL WITH EXECUTE AS OWNER, SCHEMABINDING, NATIVE_COMPILATION AS BEGIN ATOMIC WITH (TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = N'us_english') UPDATE dbo.Departments SET kitchen_count = ISNULL(kitchen_count, 0) + @kitchen_count WHERE id = @dept_id END; GO Questa procedura è tratta direttamente dal sito Microsoft riportato sopra. Esempio CREATE PROCEDURE Inserimento_Prestito @IDsocio int NOT NULL, @IDtesto int NOT NULL AS BEGIN DECLARE @oggi DECLARE @scadenza @oggi = GETDATE ( ) @scadenza = 90 + GETDATE ( ) IF (@IDtesto NOT IN SELECT @IDtesto FROM Prestiti_Correnti) INSERT INTO Prestiti_Correnti VALUES (@IDsocio, @IDtesto, @oggi, @scadenza) END; GO Questa procedura è finalizzata all’inserimento di un prestito di un libro. I due parametri servono per ricevere in chiamata le chiavi primarie rispettivamente dell’iscritto alla biblioteca e del testo richiesto. Le due variabili locali sono utilizzate per impostare la data del prestito e la scadenza. Prof. Andrea Zoccheddu ITI G. M. ANGIOY SASSARI Dispensa DB Dispensa 21 - MS T-SQL pag. 19 Parametri I parametri di una STORED PROCEDURE sono analoghi ai parametri di una funzione di un linguaggio imperativo. I nomi dei parametri devono iniziare con @ e sono seguiti dal tipo e dalle opzioni che sono dei vincoli. Il nome del parametro deve essere conforme alle regole per gli identificatori. Poiché i parametri sono locali rispetto alla procedura, è possibile utilizzare gli stessi nomi di parametro in altre procedure. È possibile dichiarare fino a 2.100 parametri per una procedura. Il valore di ogni parametro dichiarato deve essere specificato dall'utente quando viene chiamata la procedura, a meno che non venga indicato un valore predefinito per il parametro oppure il valore venga impostato in modo da corrispondere a quello di un altro parametro. Se una procedura contiene parametri con valori di tabella e nella chiamata il parametro non è presente, viene passata una tabella vuota. I parametri possono rappresentare solo espressioni costanti, non nomi di tabella, nomi di colonna o nomi di altri oggetti di database. Tutti i tipi di dati Transact-SQL possono essere utilizzati come parametri. Per creare parametri con valori di tabella è possibile utilizzare il tipo di tabella definito dall'utente. I parametri con valori di tabella possono essere solo parametri di input e devono essere associati al vincolo READONLY. I parametri possono avere alcuni vincoli o opzioni riportate di seguito: OPZIONE SIGNIFICATO DEFAULT OUT | OUTPUT READONLY NULL | NOT NULL Valore predefinito per un parametro. Se per un parametro viene definito un valore predefinito, la procedura può essere eseguita senza specificare un valore per tale parametro. Il valore predefinito deve essere una costante oppure NULL. Il formato del valore della costante può essere un carattere jolly; in questo modo sarà possibile utilizzare la parola chiave LIKE quando si passa il parametro nella procedura. Indica che si tratta di un parametro di output. Utilizzare i parametri OUTPUT per restituire i valori al chiamante della procedura. I parametri text, ntext e image non posso essere utilizzati come parametri OUTPUT, a meno che non si tratti di una procedura CLR. Un tipo di dati con valori di tabella non può essere specificato come parametro di output di una procedura. Indica che il parametro non può essere aggiornato o modificato all'interno del corpo della procedura. Se si tratta di un tipo di parametro con valori di tabella, è necessario specificare la parola chiave READONLY. Determina se i valori Null sono supportati in un parametro. Il valore predefinito è NULL. Esempio CREATE PROCEDURE Prova @data DATE DEFAULT '01/01/2014' , --se non si indica vale 01/01/2014 @rende INT OUT , --indica un parametro per risultati (in uscita) @fisso INT READONLY , --indica un parametro che non può essere modificato @obbligo INT NOT NULL , --indica un parametro obbligatorio @vuoto INT NULL , --indica un parametro che ammette il valore NULL AS BEGIN . . . END; Per approfondimenti si rimanda al manuale di uso di SQL Server Management Studio. Invocazione L’invocazione di una STORED PROCEDURE può avvenire dall’interno mediante il comando EXECUTE (contratto anche in EXEC) oppure dall’esterno impiegando una chiamata da un linguaggio che possa interagire col DBMS. Esempio EXECUTE Bibliox.Inserimento_Prestito @IDsocio = 123, @IDtesto = 904; EXECUTE Kitchen.usp_add_kitchen @dept_id = 502, @kitchen_count = 706; EXECUTE Scuola.Prova @data = NULL, @fisso = 13, @obbligo = 17, @vuoto = NULL L’invocazione può avvenire specificando i parametri oppure affidandosi alla loro posizione; le seguenti invocazioni sono tutte equivalenti: Esempio EXECUTE Scuola.Inserimento_Studenti @Cognome = N'Carri', @Nome = N'Guido'; EXECUTE Scuola.Inserimento_Studenti N'Carri', N'Guido'; EXEC Scuola.Inserimento_Studenti N'Carri', N'Guido';; Prof. Andrea Zoccheddu ITI G. M. ANGIOY SASSARI Dispensa DB Dispensa 21 - MS T-SQL pag. 20 FUNCTION IN T-SQL Sintassi generale Fonte (informazione tratta dal seguente sito) : http://msdn.microsoft.com/it-it/library/ms186755.aspx Crea una funzione definita dall'utente in SQL Server e nel Database SQL di Windows Azure. Una funzione definita dall'utente è una routine Transact-SQL o Common Language Runtime (CLR) tramite cui vengono accettati parametri, viene effettuata un'azione, ad esempio un calcolo complesso, e viene restituito il risultato di tale azione sotto forma di valore. Il valore restituito può essere un valore scalare (singolo) o una tabella. Utilizzare questa istruzione per creare una routine riutilizzabile che può essere utilizzata in queste modalità: Nelle istruzioni Transact-SQL, ad esempio SELECT. Nelle applicazioni che chiamano la funzione. Nella definizione di un'altra funzione definita dall'utente. Per parametrizzare una vista o per migliorare le funzionalità di una vista indicizzata. Per definire una colonna di una tabella. Per definire un vincolo CHECK su una colonna. Per sostituire una stored procedure. Gran parte della sintassi della funzione è analoga alla stored procedure, per cui si rimanda alla trattazione sopra esposta e agli approfondimenti sul sito Microsoft. A differenza della procedura tuttavia la funzione rende qualcosa; la funzione può rendere un valore scalare (un qualsiasi tipo predefinito di SQL oppure un tipo definito dall’utente nello schema) oppure una tabella. OPZIONE SIGNIFICATO Nome dello schema a cui appartiene la funzione definita dall'utente. SCHEMA_NAME Nome della funzione definita dall'utente. I nomi di funzione devono essere conformi alle regole per gli FUNCTION_NAME identificatori ed essere univoci all'interno del database e rispetto al relativo schema. Specifica l'ordine in base a cui vengono restituiti i risultati dalla funzione con valori di tabella. ORDER (<ORDER_CLAUSE>) Le funzioni scalari restituiscono un singolo valore e la relativa sintassi è la seguente: Definizione --Transact-SQL Scalar Function Syntax CREATE FUNCTION [ schema. ] NOME_FUNZIONE ( elenco dei parametri ) RETURNS tipo_reso AS BEGIN --corpo della funzione RETURN espressione_scalare END Le funzioni tabellari restituiscono una tabella e la relativa sintassi è la seguente: Definizione --Transact-SQL Scalar Function Syntax CREATE FUNCTION [ schema. ] NOME_FUNZIONE ( elenco dei parametri ) RETURNS TABLE AS BEGIN --corpo della funzione RETURN comando_SELECT END Prof. Andrea Zoccheddu ITI G. M. ANGIOY SASSARI Dispensa DB Dispensa 21 - MS T-SQL pag. 21 Esempio di funzione scalare CREATE FUNCTION Numero_Studenti_Maggiorenni ( @anno char(1) = '0', ) RETURNS int AS BEGIN SET NOCOUNT ON; DECLARE @ris int; SELECT @ris = COUNT(*) FROM Studenti , Classi WHERE Studenti.Classe = Classi.IDClasse AND = Classi.Anno = @anno; RETURN @ris; END Esempio di funzione tabellare CREATE FUNCTION Elenco_Studenti_Maggiorenni ( @anno char(1) = '0', ) RETURNS TABLE AS BEGIN SET NOCOUNT ON; DECLARE @ris int; RETURN SELECT @ris = COUNT(*) FROM Studenti , Classi WHERE Studenti.Classe = Classi.IDClasse AND = Classi.Anno = @anno; END Prof. Andrea Zoccheddu ITI G. M. ANGIOY SASSARI
© Copyright 2024 Paperzz