Realizzazione di un servizio di prenotazione risorse on line in SQL 24 Febbraio 2008
Posted by gianfrasoft in Transact SQL.Tags: prenotazione, risorse, servizio, sql, sql server, transact
trackback
Introduzione
Questo documento e tutto il lavoro che ne è scaturito, hanno come obiettivo la progettazione e l’implementazione di un sistema informatico che risponda alle richieste contenute nelle linee guida riportate di seguito: si è proceduto alla progettazione di una base dati per il supporto di un sistema informatico che realizzi un servizio web per la gestione di un insieme condiviso di risorse hardware per un dipartimento. Questo sistema informativo consente la prenotazione delle risorse da parte di utenti registrati, oltre a fornire come servizio la possibilità di verificare la disponibilità di una risorsa in uno specifico giorno ed in uno specifico orario.
Sono state così implementate tutte le funzionalità di:
- inserimento di una risorsa
- registrazione degli utenti
- consultazione delle risorse disponibili
- prenotazione delle risorse
- cancellazione di una prenotazione
- memorizzazione di dati relativi a utenti, risorse e prenotazioni
Strategia di progetto
Già nell’ambito delle linee guida si possono identificare le entità principali attorno alle quali il sistema informativo deve svilupparsi, e cioè: l’utente, la risorsa e la prenotazione.
Al fine di rendere il sistema quanto più possibile aperto e funzionale, si è ritenuto opportuno introdurre alcune ulteriori specifiche riguardanti le suddette entità:
- gli utenti del sistema si dividono in due categorie: amministratori e utenti semplici; ai primi è dato potere di accedere ad ogni parte del sistema mentre ai secondi alcune aree di lavoro sono interdette;
- ad ogni risorsa sono associati orari di disponibilità, cioè intervalli temporali all’esterno dei quali la risorsa non può mai essere prenotata;
- alla prenotazione delle risorse da parte di utenti generici o di amministratori viene fornito un sistema di visualizzazione grafica degli intervalli temporali di disponibilità della risorsa che rende superfluo qualsiasi ulteriore accorgimento;
- viene implementato a scopo didattico un semplice metodo di storicizzazione delle informazioni relativamente all’entità prenotazione che consente di aggirare alcuni problemi relativi all’aggiornamento delle risorse.
Definizioni
Riportiamo la prima parte di un glossario utile alla comprensione delle specifiche di lavoro come di seguito riportate:
Indicheremo con risorsa l’oggetto d’interesse di una prenotazione. Con la parola utente faremo riferimento ad un qualsiasi utente, con utente semplice o amministratore indicheremo invece gli utenti specifici.
Con la parola prenotabilità faremo riferimento alle ore in cui una risorsa risulta prenotabile, con disponibilità indicheremo le ore in cui la risorsa è prenotabile e libera: una risorsa prenotabile sarà pertanto disponibile in una particolare fascia oraria solo qualora non vi fossero già presenti in quelle ore altre prenotazioni.
I giorni di prenotabilità di una risorsa si indicheranno come giornate, ed anche queste verranno rappresentate nel database nell’ambito di una specifica entità che si chiamerà giorno.
Nell’ambito del database tutti gli oggetti di cui sopra saranno identificabili nell’ambito di entità che porteranno i nomi di: Risorse, Prenotazioni, Utenti (entità omogenea per utenti semplici ed amministratori) e Giorni.
Entià
Nell’ambito della progettazione concettuale dobbiamo per primo identificare le entità che partecipano al progetto. Abbiamo descritto in un primo momento tre entità: utenti, risorse e prenotazioni.
Al fine di rendere alcune funzionalità relative alle prenotazioni e di cui parleremo in seguito, anticipiamo che tra le altre viene introdotta una quarta entità che è il giorno.
Utenti
Si dividono in utenti semplici ed amministratori. Agli amministratori soltanto è riservato il potere di
- generare nuove risorse, modificarne o eliminarne di esistenti
- registrare nuovi utenti, modificarne o cancellarne di esistenti
Sia gli utenti semplici che gli amministratori possono prenotare risorse o cancellare prenotazioni proprie. Infine gli utenti semplici possono accedere alle informazioni associate a sé stessi per modificarne il contenuto mentre gli amministratori possono modificare le specifiche di qualsiasi utente presente in archivio.
L’entità utente contiene informazioni come: nome e cognome, indirizzo, contatti di vario genere oltre che login e password indispensabili per identificarsi nell’ambito del sistema informativo.
Risorse
Le risorse sono caratterizzate principalmente dalla propria descrizione. La generalità del concetto di risorsa è resa, nell’ambito del sistema informativo che stiamo descrivendo, ad un livello di astrazione tale da potersi considerare slegata dal contesto previsto nell’ambito delle linee guida. Parlare di risorsa hardware di un dipartimento equivale in questo contesto ad una qualsiasi risorsa prenotabile in un qualsiasi altro contesto.
Oltre alla descrizione, la risorsa è caratterizzata da una lista di (massimo) tre intervalli temporali (almeno uno deve essere valorizzato) che consentono al sistema di identificare le fasce orare di prenotabilità della risorsa nell’ambito di tutti i giorni della settimana.
Si noti che in questo contesto si assume che la risorsa sia disponibile tutti i giorni senza alcuna limitazione sulla data (limitazione che avrebbe richiesto l’introduzione di numerose variazioni nella gestione del front-end del sistema informativo). E’ altresì consentito indicare gli orari di prenotabilità a livello di risorsa che saranno il punto di riferimento per la definizione della prenotabilità nell’ambito di ogni singola giornata.
Prenotazioni
Le prenotazioni rappresentano relazioni che legano gli utenti alle risorse. In quanto tali le prenotazioni dovranno contenere null’altro che le informazioni indispensabili per la loro identificazione temporale e cioè data, orario di inizio ed orario di fine oltre ai riferimenti a risorsa ed utente.
La possibilità di prenotare una risorsa in una specifica data ed in una specifica fascia oraria richiede una verifica della sua disponibilità (e pertanto anche della sua prenotabilità) nella data/ora della nuova prenotazione. La presenza di altre prenotazioni in quella stessa fascia oraria, infatti invalida una qualsiasi nuova prenotazione, e lo stesso vale se la scelta di un intervallo per quest’ultima non ricade perfettamente nell’ambito della prenotabilità della risorsa stessa.
Problema della modifica della disponibilità di una risorsa
Se nell’ambito di una risorsa vengono modificati gli intervalli di disponibilità della stessa lì dove questa è già stata coinvolta una o più prenotazioni, nasce il problema di dovere definire una politica di comportamento del sistema informativo che aggiri la possibilità di conflitto tra gli intervalli di prenotazioni già effettuate e quelli delle nuove fasce di prenotabilità.
La politica di risoluzione del problema va in realtà determinata nell’ambito delle esigenze specifiche di chi commissiona la realizzazione del progetto. Avendo in questo ambito la libertà di determinare il più opportuno funzionamento da parte del sistema, si è deciso di provvedere descrivendo una nuova entità che ha il nome di giorno.
Giorni
Ciascuna entità di questa specie registra la prenotabilità della risorsa nell’ambito di una specifica giornata del calendario. La singola entità giorno conterrà oltre ad una data (relativa ad un qualsiasi giorno della settimana o del mese) le informazioni riguardo le fasce orarie di prenotabilità della risorsa al momento in cui, in quella specifica giornata, la prenotabilità sia stata definita una volta e per sempre.
Infatti, al momento di una prenotazione il sistema informativo farà riferimento, per la verifica della prenotabilità di una risorsa in una specifica giornata, alla entità giorno relativa alla risorsa e che fa riferimento alla giornata in questione. Se questa entità non è presente in archivio, il sistema informativo si occuperà di generarla assegnandole come data la giornata in cui si desidera attuare la prenotazione e come fasce di disponibilità quelle della risorsa che si desidera prenotare, così come sono definite in quel momento.
Pertanto le prenotazioni non faranno riferimento direttamente alle fasce orarie come descritte nella entità risorsa ma a quelle descritte nella entità giorno relativa alla data visitata.
Il fatto che la modifica delle fasce orarie di prenotabilità di ogni risorsa non si modifichi la prenotabilità come descritta nei giorni relative alla risorsa stessa, fa sì che le prenotazioni restino consistenti. Ciò equivale a dire che: qualora una risorsa venisse prenotata in uno specifico giorno ed in una specifica fascia oraria, eventuali modifiche alle fasce di disponibilità non interesserebbero i giorni in cui già fossero state effettuate prenotazioni.
Note
Questa politica di risoluzione del conflitto tra prenotazioni e risorse è sicuramente una politica discutibile sotto numerosi aspetti: sia perché non consente di stabilire il giorno in cui debba entrare in vigore il nuovo orario della risorsa, sia perché il cambio di orario determina per un numero imprecisato di giorni una alternanza di orari vecchi e nuovi a seconda della presenza o meno di prenotazioni che facciano riferimento a quelle giornate.
Una possibile migliore risposta alla questione dei conflitti prenotazioni-risorse è l’introduzione di un sistema di storicizzazione della modifica delle fasce orarie delle risorse che consentisse di registrare il periodo di validità dei vecchi e nuovi orari.
Questa soluzione, come numerose altre, sono state scartate per motivi di tempo.
Strategia di progetto
Data la semplicità della struttura della base dati, non ha propriamente senso parlare di strategie implementative di tipo top-down o bottom-up anche se per questo progetto vale forse parlare di strategia inside-out.
Partendo dalla entità che rappresenta il nucleo centrale di tutto il progetto, l’entità risorsa, possiamo considerare le entità utente e prenotazione come introdotte immediatamente dopo ed al fine di rendere la funzionalità legata alla prenotazione delle risorse stesse. Infine l’entità giorno interviene per risolvere problemi di progettazione legati alla struttura del database.
Progettazione logica
Per quanto detto sopra, le tabelle saranno quindi le seguenti:
(Utenti, Risorse, Prenotazioni, Giorni)
Schema logico
Ecco come appare la struttura sin qui descritta e realizzata logicamente mediante il case Embarcadero E/R Studio:
In questo modello entità-relazione la strutturazione logica mostra le relazioni che legano la tabella delle prenotazioni da tutte le altre tabelle. La tabella dei giorni è in relazione con la sola tabella delle risorse mentre quella degli utenti è completamente indipendente dalle altre.
Uno schema tanto semplice è tale da coincidere quasi perfettamente con la struttura implementativa del database.
Si noti nel report la presenza di due tipi dato definiti per rendere omogeneo l’utilizzo di campi che fanno riferimento ad indirizzi e-mail (tipo definito: EMAIL) ed a numeri telefonici (tipo definito: NUMEROTEL).
Funzionalità trasparenti
Alcune funzionalità del database hanno lo scopo di preservare l’integrità dei dati o di fornire controlli di vario genere sulla qualità dei dati immessi.
Alcune di queste sono state implementate per mezzo di trigger, altre per mezzo di procedure (o funzioni database) opportunamente inserite nel codice richiamato dal client del sistema informatico.
Integrità a livello di prenotazione
La cancellazione di una risorsa o di un utente dalla relativa tabella determina la necessità di ripulire le tabelle dei giorni e delle prenotazioni da tutti gli elementi che fanno riferimento alla risorsa o all’utente stesso. Questo viene reso mediante l’uso di due trigger sulle tabelle delle risorse e degli utenti.
Storicizzazione delle risorse
Come accennato precedentemente, s’intende far corrispondere alla eliminazione di un elemento della tabella delle risorse l’aggiornamento del campo Storicizzazione al fine di tenere in archivio traccia della risorsa non più utilizzata.
Una simile storicizzazione può essere attuata anche a livello di aggiornamento (dove la modifica di un qualsiasi campo della tabella Risorse genera una copia del record come era prima della modifica e con una data di validità introdotta nel campo Storicizzazione). Questo tipo di impiego non è utile in questa fase anche se renderebbe possibile alcune migliorie nel funzionamento della base dati.
Nell’ambito della visualizzazione, nel client, della lista delle risorse disponibili in archivio vengono pertanto escluse nella query tutte le risorse con campo Storicizzazione non nullo.
Controllo della disponibilità di una risorsa
Alcune funzionalità, che non possono essere rese agevolmente mediante semplici query, devono essere affidare a procedure (o funzioni) apposite: è il caso dei controlli sulla disponibilità delle risorse nelle fasce orarie in cui è richiesto di aggiungere una prenotazione. Il sistema database deve essere blindato, nel senso di non consentire procedure di INSERT di prenotazioni dove non fesse consentito.
Questi controlli sono resi trasparenti dal client che interroga il database con una apposita stored procedure per verificare che non si stiano violando le regole fondamentali della prenotabilità delle risorse: qualora le regole fossero violare, a lui è riservato il compito di annullare la procedura di inserimento ed avvertire l’utente della non avvenuta operazione. Un ulteriore controllo a livello database, affidato ad un trigger e pertanto trasparente anche al client stesso potrebbe ritenersi opportuno ma attualmente appare superfluo.
Anche con l’introduzione nel front-end di un sistema guidato alla prenotazione, realizzato mediante l’uso delle procedure di cui ai paragrafi seguenti, è da ritenersi necessario il controllo appena descritto per non permettere di introdurre in alcun modo in archivio dati che renderebbero aleatorio tutto il contenuto delle tabelle destinate alle prenotazioni.
Controllo della presenza del giorno di prenotabilità
In fase di interrogazione del database, è necessario che, qualora non fosse definita la prenotabilità di una risorsa in una specifica giornata, che corrisponde alla assenza del record della tabella dei giorni che fa riferimento a quella risorsa e quella giornata, sarà necessario generare quel record in modo da riprodurre tutte le fasce orarie di disponibilità della risorsa stessa.
Le fasce orarie saranno quelle della risorsa al momento della creazione del record nella tabella Giorni; ad una procedura sarà affidato il controllo della presenza dello specifico record della tabella Giorni e l’eventuale sua generazione qualora non fosse presente.
NOTA: La generazione dei record della tabella Giorni avverranno pertanto già in fase di visitazione della tabella stessa. Questo comportamento rappresenta una approssimazione forse grossolana alla quale si potrebbe ovviare in molti modi ma che si assume adatto alle esigenze di questo progetto.
Funzionalità accessorie
Calcolo automatico dell’id di una nuova risorsa
E’ spesso opportuno rendere automatico il calcolo, da parte del sistema informatico, del nuovo valore del campo chiave della tabella delle risorse (uguale al valore massimo presente in tabella aumentato di uno). Metodi più evoluti, mediante tabella delle sequenze sarebbero opportuni per applicazioni web destinate ad un numero di connessioni contemporanee alto, ma in questo progetto si considerano non necessari.
Generazione di viste sulle fasce orarie di disponibilità delle risorse
Una particolare “funzione tabellare” (strumento in uso in MS-SQL Server 2000) restituirà in output una tabella ad uso della visualizzazione delle fasce orarie di prenotazione e di disponibilità delle risorse al fine di consentire, nel client, una visualizzazione grafica.
Nella visualizzazione grafica compariranno tanti elementi quanti sono i time-slice interessati dall’intervallo di prenotabilità della risorsa: ogni elemento corrisponderà ad un record della tabella dinamica generata dalla funzione tabellare. Un particolare campo di questa tabella servirà ad indicare se nella specifica fascia oraria la risorsa è non disponibile, prenotabile o già prenotata: a questi valori il client farà corrispondere in visualizzazione colori diversi che rendano più intuitiva la lettura.
Indicazione degli estremi di un intervallo di disponibilità
Sempre al fine di generare funzionalità utili alla visualizzazione grafica sul lato client delle informazioni relative alla disponibilità delle risorse nelle specifiche fasce orarie, una particolare procedura si occuperà di determinare l’inizio e la fine di un intervallo di disponibilità a partire da un qualsiasi orario contenuto all’interno dell’intervallo stesso.
In fase di visualizzazione da parte del client, l’utilità di questa procedura è di rendere possibile all’utente di sapere se in un intorno di uno specifico orario, selezionato sulla grafica descritta sopra, esiste la possibilità di prenotare una risorsa e quanto può essere al limite grande questo intervallo.
Altri controlli
Al client dovranno essere affidati numerosi altri controlli sulla qualità dei dati in fase di inserimento o di modifica dei record; ciò si attua al fine sia di evitare l’inserimento di dati aleatori per i quali non sono previsti controlli a livello di database, sia di evitare che il database restituisca errori non gestiti dallo stesso client.
Implementazione
Quello che segue è la descrizione dettagliata del file usato per la generazione delle entità del database oggetto di studio, oltre ai tipi definiti dall’utente, ai trigger ed alle procedure ad uso della gestione del sistema informatico.
Si noti che nel database reale i nomi dei campi e delle entità sono leggermente modificati rispetto a come compaiono nella strutturazione logica. In particolare gli spazi sono sostituiti da caratteri underscore (“_”) e le lettere minuscole sono sostituite da maiuscole; così che il campo “Disp dalle” diventa “DISP_DALLE”.
Tipi definiti
“EMAIL”
EXEC sp_addtype EMAIL, “varchar(100)”,”NULL”
“NUMEROTEL”
EXEC sp_addtype NUMEROTEL, “varchar(20)”,”NULL”
Questi tipi definiti sono introdotti per rendere omogeneo l’utilizzo dei campi relativi ad e-mail e numeri telefonici.
Entità
Le entità sono riportate nell’ordine logico con cui sono state concepite in fase di progettazione concettuale.
Risorse
CREATE TABLE RISORSE(
ID_RISORSA int NOT NULL,
NOME varchar(30) NOT NULL,
DISP_DALLE datetime NOT NULL,
DISP_ALLE datetime NOT NULL,
DISP2_DALLE datetime NULL,
DISP2_ALLE datetime NULL,
DISP3_DALLE datetime NULL,
DISP3_ALLE datetime NULL,
STORICIZZAZIONE datetime NULL,
PRIMARY KEY NONCLUSTERED (ID_RISORSA)
)
Utenti
CREATE TABLE UTENTI(
LOGIN varchar(20) NOT NULL,
PASSWORD varchar(20) NOT NULL,
NOME varchar(100) NOT NULL,
COGNOME varchar(100) NOT NULL,
DOM_INDIRIZZO varchar(200) NULL,
DOM_CITTA varchar(100) NULL,
TELEFONO NUMEROTEL NULL,
CELLULARE NUMEROTEL NULL,
E_MAIL EMAIL NULL,
TIPO char(1) NULL,
PRIMARY KEY NONCLUSTERED (LOGIN)
)
Giorni
CREATE TABLE GIORNI(
GIORNO datetime NOT NULL,
ID_RISORSA int NOT NULL,
DISP_DALLE datetime NOT NULL,
DISP_ALLE datetime NOT NULL,
DISP2_DALLE datetime NULL,
DISP2_ALLE datetime NULL,
DISP3_DALLE datetime NULL,
DISP3_ALLE datetime NULL,
PRIMARY KEY NONCLUSTERED (GIORNO,ID_RISORSA)
)
Prenotazioni
CREATE TABLE PRENOTAZIONI(
GIORNO datetime NOT NULL,
DA_ORA datetime NOT NULL,
ID_RISORSA int NOT NULL,
A_ORA datetime NOT NULL,
LOGIN varchar(20) NULL,
PRIMARY KEY NONCLUSTERED (GIORNO,DA_ORA,ID_RISORSA)
)
Chiavi alternative
E’ presente in archivio una sola chiave alternativa che consente di individuare una risorsa mediante il suo nome ed il valore di storicizzazione.
AK1_RISORSE
Il campo storicizzazione fa chiave univoca con il campo Nome al fine di consentire la reintroduzione di elementi precedentemente storicizzati con un nuovo id primario ma non di introdurre due risorse attuve (campo Storicizzazione nullo) con lo stesso nome.
CREATE UNIQUE INDEX AK1_RISORSE ON RISORSE(NOME,STORICIZZAZIONE)
Chiavi esterne
Le foreign key vengono generate mediante il comando di ALTER TABLE al fine di non creare conflitti con le tabelle non ancora generate.
FK_RISORSE_DISPONIBILITA
Questa chiave mette in relazione la tabella Giorni con la tabella Risorse: individua pertanto la risorsa a cui fa riferimento lo specifico giorno.
ALTER TABLE GIORNI ADD CONSTRAINT FK_RISORSE_DISPONIBILITA
FOREIGN KEY (ID_RISORSA)
REFERENCES RISORSE(ID_RISORSA)
FK_GIORNI_PRENOTAZIONI
Questa chiave mette in relazione la tabella Prenotazioni con la tabella Giorni: individua a quale giorno fa riferimento la specifica prenotazione.
ALTER TABLE PRENOTAZIONI ADD CONSTRAINT FK_GIORNI_PRENOTAZIONI
FOREIGN KEY (GIORNO,ID_RISORSA)
REFERENCES GIORNI(GIORNO,ID_RISORSA)
FK_RISORSE_PRENOTAZIONI
Questa chiave mette in relazione la tabella Prenotazioni con la tabella Risorse: individua la risorsa alla quale fa riferimento la specifica prenotazione.
ALTER TABLE PRENOTAZIONI ADD CONSTRAINT FK_RISORSE_PRENOTAZIONI
FOREIGN KEY (ID_RISORSA)
REFERENCES RISORSE(ID_RISORSA)
Questa informazione è ridondante se si considera che ogni prenotazione fa riferimento ad un record della tabella Giorni e che quest’ultimo contiene già il riferiento alla risorsa prenotata. Ripetere questa informazione nella tabella delle prenotazioni consente comunque un risparmio in termini computazionali e di tempo di risposta del database poiché, in fase di interrogazione dello stesso, consentirà di fare uso di query semplificate. La spesa in termini di inserimento dell’informazione sulla risorsa nei record delle prenotazioni non ha alcun costo perché già disponibile nel client al momento in cui un utente desidera prenotare.
FK_UTENTI_PRENOTAZIONI
Questa chiave mette in relazione la tabella Prenotazioni con la tabella Utenti: individua l’utente che ha effettuato la specifica prenotazione.
ALTER TABLE PRENOTAZIONI ADD CONSTRAINT FK_UTENTI_PRENOTAZIONI
FOREIGN KEY (LOGIN)
REFERENCES UTENTI(LOGIN)
Trigger
Hanno tutti lo scopo di mantenere l’integrità del database.
OnDeleteRisorsa
Determina il comportamento del satabase al momento della eliminazione di una risorsa. E’ un trigger INSTEAD OF perché intende sostituire alla operazione di eliminazione l’aggiornamento del campo STORICIZZAZIONE.
CREATE TRIGGER OnDeleteRisorsa
ON RISORSE
INSTEAD OF DELETE
AS
BEGIN
DECLARE @IdRisorsa int
–Il cursore RisorseEliminate serve ad enumerare tutti i record eliminati
–(qualora l’eliminazione ne coinvolgesse piu di uno) e per essi attuare la stessa politica.
DECLARE RisorseEliminate CURSOR FOR
SELECT ID_RISORSA FROM deleted
OPEN RisorseEliminate
FETCH NEXT FROM RisorseEliminate
INTO @IdRisorsa
WHILE @@FETCH_STATUS = 0
BEGIN
–Elimina tutti i record della tabella PRENOTAZIONI collegati alla ciascuna risorsa eliminata.
DELETE FROM PRENOTAZIONI
WHERE ID_RISORSA = @IdRisorsa
UPDATE RISORSE SET
– Alla operazione di DELETE sostituisce l’UPDATE del campo STORICIZZAZIONE. STORICIZZAZIONE = getdate()
WHERE ID_RISORSA = @IdRisorsa
FETCH NEXT FROM RisorseEliminate
INTO @IdRisorsa
END
CLOSE RisorseEliminate
DEALLOCATE RisorseEliminate
END
OnDeleteRisorsa
Determina il comportamento del satabase al momento della eliminazione di un UTENTE. Anche questo è un trigger di tipo INSTEAD OF ma in questo caso avrebbe potuto essere anche di tipo AFTER: la sola condizione che si pone è che l’operazione di eliminazione dell’utente stesso non deve avvenire se non dopo l’eliminazione dei riferimenti ad esso nella tabella PRENOTAZIONI.
CREATE TRIGGER OnDeleteUtente
ON UTENTI
INSTEAD OF DELETE
AS
BEGIN
DECLARE @LoginUtente varchar(20)
– Il cursore UtentiEliminati serve ad enumerare tutti i record eliminati
– (qualora l’eliminazione ne coinvolgesse piu di uno) e per essi attuare la stessa politica.
DECLARE UtentiEliminati CURSOR FOR
SELECT LOGIN FROM deleted
OPEN UtentiEliminati
FETCH NEXT FROM UtentiEliminati
INTO @LoginUtente
– Elimina tutti i record della tabella PRENOTAZIONI collegati alla ciascun utente eliminato. WHILE @@FETCH_STATUS = 0
BEGIN
DELETE FROM PRENOTAZIONI
WHERE LOGIN = @LoginUtente
– Elimina per ultimo tutti i record della tabella UTENTI come richiesto dalla operazione di DELETE.
DELETE FROM UTENTI
WHERE LOGIN = @LoginUtente
FETCH NEXT FROM UtentiEliminati
INTO @LoginUtente
END
CLOSE UtentiEliminati
DEALLOCATE UtentiEliminati
END
Stored procedure
Le procedure che seguono sono concepite per rendere i controlli e le funzionalità relative al calcolo delle fasce orarie di disponibilità delle risorse.
AbilitaPrenotabilitaRisorsa
Questa funzione verifica che per una specifica risorsa ed una specifica data sia prensente nella tabella GIORNI il record che ne consente la prenotazione, altrimenti lo genera.
CREATE PROCEDURE AbilitaPrenotabilitaRisorsa
(@IdRisorsa int,
@Data datetime)
AS
BEGIN
– Verifica chen non esista già in archivio un record in GIORNI che faccia riferimento alla
– risorsa ed alla giornata dati per input.
IF NOT EXISTS (SELECT * FROM GIORNI
WHERE ID_RISORSA = @IdRisorsa
AND GIORNO = @Data)
BEGIN
INSERT INTO GIORNI (GIORNO, ID_RISORSA,
– Se non esiste lo genera introducendo nei campi destinati a definire gli intervalli di
– prenotabilità i valori contenuti nei campi omologhi della tabella delle risorse
DISP_DALLE, DISP_ALLE,
DISP2_DALLE, DISP2_ALLE,
DISP3_DALLE, DISP3_ALLE)
SELECT @Data, ID_RISORSA,
DISP_DALLE, DISP_ALLE,
DISP2_DALLE, DISP2_ALLE,
DISP3_DALLE, DISP3_ALLE
FROM RISORSE
WHERE ID_RISORSA = @IdRisorsa
END
END
TrovaInizioFineIntervallo
Questa procedura restituisce gli orari di inizio e di fine di un intervallo di prenotabilità riferito alla data ed all’ora passati come parametri di input.
CREATE PROCEDURE TrovaInizioFineIntervallo
(@IdRisorsa int,
@Data datetime,
@Orario datetime,
@OraInizioIntervallo datetime OUTPUT,
@OraFineIntervallo datetime OUTPUT)
AS
– Se esiste una prenotazione che insiste sulla fascia oraria selezionata la procedura restituisce “2” ed esce.
BEGIN
– Errore codice 1
IF EXISTS (SELECT * FROM PRENOTAZIONI
WHERE GIORNO = @Data
AND ID_RISORSA = @IdRisorsa
AND DA_ORA <= @Orario
AND A_ORA > @Orario)
BEGIN
RETURN 2
END
– Altrimenti genera una tabella temporanea #TempTable in cui introduce una serie di elementi che
– servono a determinare in prima istanza il valore dell’estremo sinistro dell’intervallo di
– prenotabilità (e quindi di disponibilità) della risorsa. In una seconda istanza consentirà di
– determinare l’estremo destro dello stesso intervallo.
CREATE TABLE #TempTable (ALLE datetime)
INSERT INTO #TempTable
SELECT MAX(A_ORA) FROM PRENOTAZIONI
WHERE GIORNO = @Data
AND ID_RISORSA = @IdRisorsa
AND A_ORA <= @Orario
UNION
SELECT MAX(DISP_DALLE) FROM GIORNI
WHERE GIORNO = @data
AND ID_RISORSA = @IdRisorsa
– Per determinare l’estremo sinistro, seleziona il massimo tra gli estremi destri degli intervalli
– di prenotazione e degli estremi sinistri degli intervalli di disponibilità della risorsa
– relativamente alla data selezionata.
AND DISP_DALLE <= @Orario
UNION
SELECT MAX(DISP2_DALLE) FROM GIORNI
WHERE GIORNO = @data
AND ID_RISORSA = @IdRisorsa
AND DISP2_DALLE <= @Orario
UNION
SELECT MAX(DISP3_DALLE) FROM GIORNI
WHERE GIORNO = @data
AND ID_RISORSA = @IdRisorsa
AND DISP3_DALLE <= @Orario
SELECT @OraInizioIntervallo = MAX(ALLE) FROM #TempTable
DELETE FROM #TempTable
– Per determinare l’estremo destro, seleziona il minimo tra gli estremi sisistri degli intervalli
– di prenotazione e degli estremi destri degli intervalli di disponibilità della risorsa
– relativamente alla data selezionata.
INSERT INTO #TempTable
SELECT MIN(DA_ORA) FROM PRENOTAZIONI
WHERE GIORNO = @Data
AND ID_RISORSA = @IdRisorsa
AND DA_ORA >= @Orario
UNION
SELECT MIN(DISP_ALLE) FROM GIORNI
WHERE GIORNO = @data
AND ID_RISORSA = @IdRisorsa
AND DISP_ALLE >= @Orario
UNION
SELECT MIN(DISP2_ALLE) FROM GIORNI
WHERE GIORNO = @data
AND ID_RISORSA = @IdRisorsa
AND DISP2_ALLE >= @Orario
UNION
SELECT MIN(DISP3_ALLE) FROM GIORNI
WHERE GIORNO = @data
AND ID_RISORSA = @IdRisorsa
AND DISP3_ALLE >= @Orario
SELECT @OraFineIntervallo = MIN(ALLE) FROM #TempTable
DROP TABLE #TempTable
PRINT @OraInizioIntervallo
PRINT @OraFineIntervallo
RETURN 0
END
GO
VerificaPrenotabilitaRisorsa
Questa procedura verifica che una risorsa sia disponibile in una particolare fascia oraria. Essa restituisce un numero che può assumere i seguenti valori:
0: la risorsa è disponibile
1: la risorsa è prenotabile ma non disponibile
2: la risorsa non è prenotabile.
CREATE PROCEDURE VerificaPrenotabilitaRisorsa
(@IdRisorsa int,
@Data datetime,
@OraDa datetime,
@OraA datetime)
AS
BEGIN
– CONTROLLO DELLE DISPONIBILITA’ –
– Errore codice 3
– Il primo controllo di questa procedura riguarda la qualità dei dati immessi. Se i dati sono
– inconsistenti restituisce 3 ed esce.
IF @OraDa >= @OraA
BEGIN
RETURN 3
END
– Errore codice 2
– Verifica che sia presente in archivio almeno un intervallo di prenotabilità che racchiuda
– completamente l’intervallo dato in input. Se non esiste restituisce 2 ed esce.
IF NOT EXISTS (SELECT * FROM GIORNI
WHERE GIORNO = @Data
AND ID_RISORSA = @IdRisorsa
AND DISP_DALLE <= @OraDa
AND DISP_ALLE >= @OraDa
AND DISP_DALLE <= @OraA
AND DISP_ALLE >= @OraA)
AND NOT EXISTS (SELECT * FROM GIORNI
WHERE GIORNO = @Data
AND ID_RISORSA = @IdRisorsa
AND DISP2_DALLE <= @OraDa
AND DISP2_ALLE >= @OraDa
AND DISP2_DALLE <= @OraA
AND DISP2_ALLE >= @OraA)
AND NOT EXISTS (SELECT * FROM GIORNI
WHERE GIORNO = @Data
AND ID_RISORSA = @IdRisorsa
AND DISP3_DALLE <= @OraDa
AND DISP3_ALLE >= @OraDa
AND DISP3_DALLE <= @OraA
AND DISP3_ALLE >= @OraA)
BEGIN
RETURN 2
END
– CONTROLLO DELLE PRENOTAZIONI –
– Errore codice 1
– Verifica che non ci siano in archivio prenotazioni che s’intreccino con l’intervallo dato in input.
– Se sì restituisce 1 ed esce.
IF EXISTS (SELECT * FROM PRENOTAZIONI
WHERE GIORNO = @Data
AND ID_RISORSA = @IdRisorsa
AND DA_ORA < @OraA
AND A_ORA >= @OraA)
BEGIN
RETURN 1
END
– Errore codice 1
IF EXISTS (SELECT * FROM PRENOTAZIONI
WHERE GIORNO = @Data
AND ID_RISORSA = @IdRisorsa
AND DA_ORA <= @OraDa
AND A_ORA > @OraDa)
BEGIN
RETURN 1
END
RETURN 0
END
Function
Le funzioni sono una prerogativa specifica del MS-SQL Server 2000. Quelle qui descritte sono concepite per in massima parte per rendere i controlli e le funzionalità relative al calcolo delle fasce orarie di disponibilità delle risorse, ma anche per altre funzionalità.
ImmaginePrenotazioni
Questa funzione restituisce una tabella strutturata in maniera tale da indicare per ciascuna data e per uno specifico time-slice. Questo particolare tipo di funzione è detto “Funzione tabellare”.
L’obiettivo di questa funzione è di fornire al client una stuttura fondamentale sulla quale poggiare per la realizzazione della grafica riguardante la disponibilità di una risorsa in un particolare giorno.
Il parametro di input @TimeSliceInMin determina la precisione nella rappresentazione delle prenotazioni e degli intervalli di prenotabilità: una piccola modifica nell’ambito del programma client può agire in maniera da passare un valore numerico differente ed avere una rappresentazione grafica migliore.
Il campo STATO della tabella @TabellaPrenotazioni indica lo stato del time slice e per esso i valori possibili sono:
‘F’: time-slice disponibile
‘O’: time-slice prenotabile ma occupato
‘N’: time-slice non prenotabile
Il parametro @ErrorCode serve ad indicare se si sono verificati degli errori.
NOTA: Questa procedura lavora su record della tabella Giorni dando per scontato che essi esistano. Infatti il client non permette di accedere alle funzionalità offerte da questa funzione se non dopo avere lanciato almeno una volta pa procedura AbilitPrenotabilitaRisorsa.
CREATE FUNCTION ImmaginePrenotazioni
(@IdRisorsa int,
@StartDate datetime,
@EndDate datetime,
@TimeSliceInMin int)
– La tabella @TabellaPrenotazioni costituisce l’output della funzione.
RETURNS @TabellaPrenotazioni TABLE
(Data datetime,
Orario datetime,
Stato char)
AS
BEGIN
– Errore codice 1
– Effettua alcuni controlli sui dati di input. Se vanno male esce.
if @EndDate < @StartDate
BEGIN
RETURN
END
– Errore codice 2
if @TimeSliceInMin < 00 OR @TimeSliceInMin > 60
BEGIN
RETURN
END
DECLARE @TempDate datetime
DECLARE @EndTempDate datetime
DECLARE @DispDalle datetime
DECLARE @DispAlle datetime
DECLARE @Disp2Dalle datetime
DECLARE @Disp2Alle datetime
DECLARE @Disp3Dalle datetime
DECLARE @Disp3Alle datetime
DECLARE @TempTime datetime
DECLARE @Stato char
– Genera un cursore, GiorniIntervallo, che consente alla procedura di funzionare anche se nei parametri
– d’ingresso è presente un intervallo di date invece che una data sola. Nell’ambito del progetto questa
– funzionalità non è sfruttata ma la generalità della procedura serve a rendere l’architettura aperta.
DECLARE GiorniIntervallo CURSOR FOR
SELECT GIORNO,
DISP_DALLE,
DISP_ALLE,
DISP2_DALLE,
DISP2_ALLE,
DISP3_DALLE,
DISP3_ALLE
FROM GIORNI
WHERE ID_RISORSA = @IdRisorsa
AND GIORNO >= @StartDate
AND GIORNO <= @EndDate
– La variabile @TempTime serve a scandire i time slice ed il suo valore viene incrementato ad
– ogni ciclo di una quantità pari al valore del parametro @TimeSliceInMin.
OPEN GiorniIntervallo
FETCH NEXT FROM GiorniIntervallo
INTO @TempDate,
@DispDalle,
@DispAlle,
– L’innesto di funzioni ISNULL presente qui sotto è un artificio che serve a determinare il massimo
– tra i valori contenuti nelle variabili coinvolte escludendo i valori nulli. Questo artificio è
– possibile perché si assume che i valori presenti nei campi @DispAlle, @Disp2Alle e @Disp3Alle siano
– crescenti mentre almeno il campo @DispAlle deve per definizione essere non nullo.
@Disp2Dalle,
@Disp2Alle,
@Disp3Dalle,
@Disp3Alle
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @TempTime = @DispDalle
SELECT @EndTempDate = ISNULL(@Disp3Alle, ISNULL(@Disp2Alle, @DispAlle))
WHILE @TempTime < @EndTempDate
BEGIN
IF (@TempTime >= @DispDalle) AND (@TempTime < @DispAlle)
OR (@TempTime >= @Disp2Dalle) AND (@TempTime < @Disp2Alle)
OR (@TempTime >= @Disp3Dalle) AND (@TempTime < @Disp3Alle)
– Il primo controllo riguarda la prenotabilità della risorsa. Se va a buon fine lo stato del
– time-slice viene posto momentaneamente a “F” (free) ad indicare che la risorsa è prenotabile e libera,
– altrimenti viene posto a “N” (non prenotabile) ad indicare che non è prenotabile.
SELECT @Stato = ‘F’
ELSE
SELECT @Stato = ‘N’
– Il secondo controllo è sulle prenotazioni e viene effettuato solo se lo stato del time-slice
– dopo il primo controllo è posto a “F”. Infatti, se esiste una qualche prenotazione che lo coinvolge
– il suo valore viene cambiato e diventa “O” (occupato).
IF @Stato = ‘F’
IF EXISTS (SELECT * FROM PRENOTAZIONI
WHERE GIORNO = @TempDate
AND ID_RISORSA = @IdRisorsa
AND DA_ORA <= @TempTime
AND A_ORA > @TempTime)
SELECT @Stato = ‘O’
INSERT INTO @TabellaPrenotazioni VALUES (@TempDate, @TempTime, @Stato)
SELECT @TempTime = DATEADD(minute, @TimeSliceInMin, @TempTime)
END
FETCH NEXT FROM GiorniIntervallo
INTO @TempDate,
@DispDalle,
@DispAlle,
@Disp2Dalle,
@Disp2Alle,
@Disp3Dalle,
@Disp3Alle
END
CLOSE GiorniIntervallo
DEALLOCATE GiorniIntervallo
RETURN
END
ImmaginePrenotazioniUtente
Questa funzione restituisce una tabella strutturata in maniera tale da indicare per l’utente selezionato tutta la lista delle prenotazioni effettuate sulle risorse in archivio.
Questa funzione fornisce al client la base per la visualizzazione delle prenotazioni, lista dalla quale selezionare le eventuali prenotazioni da cancellare.
CREATE FUNCTION ImmaginePrenotazioniUtente
(@Login varchar(20))
– Il parametro di output @TabellaPrenotazioni conterrà la lista delle prenotazioni effettuate da uno specifico utente,RETURNS @TabellaPrenotazioni TABLE
(Data datetime,
DaOra datetime,
AOra datetime,
IdRisorsa int,
NomeRisorsa varchar(30))
AS
BEGIN
INSERT INTO @TabellaPrenotazioni (Data, DaOra, AOra, IdRisorsa, NomeRisorsa)
–La query che alimenta la tabella @TabellaPrenotazioni è una semplice join tra la tabelle–delle prenotazioni e quella delle risorse.
SELECT PRENOTAZIONI.GIORNO,
PRENOTAZIONI.DA_ORA,
PRENOTAZIONI.A_ORA,
PRENOTAZIONI.ID_RISORSA,
RISORSE.NOME
FROM PRENOTAZIONI
INNER JOIN RISORSE
ON RISORSE.ID_RISORSA = PRENOTAZIONI.ID_RISORSA
WHERE LOGIN = @Login
ORDER BY PRENOTAZIONI.GIORNO,
PRENOTAZIONI.DA_ORA
RETURN
END
NuovoIdRisorse
Questa funzione serve a determinare il valore del campo ID_RISORSA per una nuova risorsa appena introdotta in archivio.
CREATE FUNCTION NuovoIdRisorse ()
RETURNS int
–La query che determina il nuovo valore per il campo ID_RISORSA calcola il massimo–valore del campo e lo aumenta di uno; se il valore è nullo restituisce 1.
AS
BEGIN
DECLARE @NuovoId int
SELECT @NuovoId = ISNULL(MAX(ID_RISORSA), 0) + 1 FROM RISORSE
RETURN @NuovoId
END
INSERT
Per concludere la generazione del database è necessario introdurre un utente standard, di tipo amministratore, che sia la base di partenza per il funzionamento di tutto il sistema informatico. Questo utente avrà un login ed una password noti (entrambi uguali ad “sa”).
INSERT INTO UTENTI (LOGIN, PASSWORD, NOME, COGNOME, TIPO)
VALUES (’sa’, ’sa’, ‘Amministratore’, ‘Standard’, ‘A’)
Commenti»
No comments yet — be the first.