Homepage  Il progetto dsy.it è l'unofficial support site dei corsi di laurea del Dipartimento di Scienze dell'Informazione e del Dipartimento di Informatica e Comunicazione della Statale di Milano. E' un servizio degli studenti per gli studenti, curato in modo no-profit da un gruppo di essi. I nostri servizi comprendono aree di discussione per ogni Corso di Laurea, un'area download per lo scambio file, una raccolta di link e un motore di ricerca, il supporto agli studenti lavoratori, il forum hosting per Professori e studenti, i blog, e molto altro...
In questa sezione è indicizzato in textonly il contenuto del nostro forum


.dsy:it. .dsy:it. Archive > Didattica > Corsi A - F > Basi di dati ~ informatica triennale
 
aiuto esercizio!!!!
Clicca QUI per vedere il messaggio nel forum
fra85
Ciao a tutti,devo implementare un vincolo date le seguenti tabelle:

ISCRITTO(codice(chiave p.),data di nascita,nome,cognome,info abbonamento(se è abbonato o meno))

FREQUENTA(codice iscritto,nome unico corso(tutte e due sono la chiave))

CORSO(nome unico(chiave),numero iscritti, numero abbonati)

Il vincolo richiesto è: un corso deve avere l'80% di iscritti che sono abbonati.

Qualcuno potrebbe aiutarmi ad implementarlo per favore :cry:?

Grazie....

fra85
allora io avevo pensato di implementarlo in questo modo,ma volevo il parere di qualcuno e inoltre devo scriverlo nella sintassi giusta per poterlo testare e quindi anche qui volevo un aiuto...

volevo creare un trigger che si attiva quando modifico la tabella corso e quindi quando si aumenta il numero di abbonati e il numero di iscritti in un corso oppure viceversa,e valuto se il numero degli abbonati è maggiore del 79% del numero degli iscritti.Se non lo è mi lancia un messaggio che mi comunica che l'80% degli isciriitti ad un corso devono essere abbonati



create trigger abbonati
after update on corso
for each row
when not exist (select numero_iscritti
from corso
where new.numero_abbonati > new.numero_iscritti * 0,79)

then signal SQLSTATE 70007 ('l'80% di iscritti deve essere abbonato')

number15
Prova così

DELIMITER $$

create trigger abbonati after update on corso
FOR EACH ROW
BEGIN
IF 0 = (SELECT COUNT(*) FROM corso WHERE new.numero_abbonati > new.numero_iscritti * 0,79 )
THEN
signal SQLSTATE 70007 ('l'80% di iscritti deve essere abbonato');
END IF;
END$$

DELIMITER ;

fra85
grazie mille sei stato gentilissimo,adesso lo provo e cerco di capire...

fra85
Una cosa ti devo chiedere,ma i trigger devo crearli dopo aver creato le tabelle vuote oppure posso crearle in un qualsiasi momento e poi testarli successivamente; come mi conviene fare più che altro

number15
Una volta che le tabelle esistono, il trigger lo puoi creare quando vuoi.
Non credo ci siano neanche problemi di 'tempi di esecuzione' a seconda del contenuto, tanto il contenuto della tabella il trigger non lo guarda.

number15
Ho riletto quello che devi fare e se ho capito bene la struttura, mi pare concettualmente sbagliato.
Il trigger (che cmq non dovrebbe andare e ti spiego dopo perché) devi farlo su FREQUENTA non su corso, i cui campi son legati a quanti iscritti/abbonati frequentano quel corso, o sbaglio?
Diciamo che ipoteticamente (se non avessi nessun vincolo da rispettare) tu con un trigger fai che ad ogni nuovo inserimento in frequenta vai ad aggiornare i numeri iscritti e abbonati in corso (e già qui direi che potresti ottenere lo stesso andando a fare delle count volanti su ISCRITTO e FREQUENTA).

Ti spiego perché il trigger non funziona in ogni caso.
Tu in pratica AFTER UPDATE controlli se il corso ha l'80% degli abbonati. Ma se non ce l'ha lui comunque ha già aggiornato.

Di sicuro direi che devi fare un BEFORE UPDATE, ma comunque non risolvi.
Di tecniche di rollback (intendo bloccare l'esecuzione del trigger dopo il controllo, cioè se vede che con quel nuovo inserimento scende sotto l'80% allora non inserisce) mi pare ci sia qualcosa, ma mi sembra anche che non siano supportate nei trigger.

Parlando sempre ipoteticamente, potresti fare una insert in una tabella temporanea e triggerare after insert in quella tabella e andando a controllare il tuo 80%. Se rispetta il vincolo allora fai la insert nella tabella corretta, altrimenti stampi l'errore del vincolo.

Spero di esser stato chiaro, altrimenti scrivimi cosa non hai capito che dopo cena vedo di risponderti.

Nel caso spiegami bene la struttura della tabella, se è tua o se è un esercizio e se il vincolo è richiesto sia su db o va bene anche a livello applicativo (cosa che quindi risolvi 'facilmente' in php o simili)

fra85
ho cercato di provarlo ma appena scrivo END$$ e vado a capo mi da errori di sintassi:

you have an error in your SQL syntax; check the manual that corresponds to your mysql server version for the right syntax to use near '79)
then
signal SQLSTATE 70007 ('lo 80% di iscritti deve essere abbonato');
END' at line 4


qual'è secondo voi il problema???

fra85
scusa ho letto adesso il messaggio precedente...

fra85
in realtà non so se ho capito bene...
Allora io dovrei creare una nuova tabella che chiamo per esempio prova e inserisco i campi codice_iscritto,info_abbonamento,corso_frequentato
e creare un trigger che dopo l'inserimento mi controlli se l'80% degli iscritti sono abbonati,se è no mi stampa l'errore e quindi capisco che il nuovo iscritto deve essere abbonato.

In poche parole devo consegnare un progetto per un'integrazione,e devo implementare quest'ultimo vincolo per la consegna che nn sono riuscita a fare :sad:.
La realizzazione dell'interfaccia web è opzionale quindi nn l'ho fatta.Se vuoi ti mando magari via mail il progetto così magari mi puoi dare meglio una mano.
Grazie di tutto,e spero di farcela...

number15
La struttura della tabelle l'hai fatta tu?
I campi numero iscritti, numero abbonati in CORSO che significato hanno? Come li gestisci?

Spiegami come funzionano i passaggi iscrizione, corso, frequenta corso.

Edit: Il vincolo richiesto è: un corso deve avere l'80% di iscritti che sono abbonati.
Nello specifico cosa significa? Che se io sono all'80% e voglio iscrivere ad un corso un non abbonato non me lo fa iscrivere?

fra85
si l'ho fatta io.Ti scrivo le cose che riguardano il progetto che penso interessano per questo vincolo:

Per iscriversi al centro occorre compilare un modulo con i seguenti dati: nome,cognome,indirizzo,codice fiscale, data di nascita,informazioni sull’abbonamento e costo dell’abbonamento.
Nel centro si possono svolgere varie attività, nei diversi impianti.
Per quanto riguarda la palestra vengono effettuati dei corsi guidati da un istruttore. I corsi vengono effettuati nella palestra apposita ai corsi.Ogni corso ha un nome unico, una breve descrizione che indica il tipo di lezione svolta e, ogni corso è diviso in sessioni di un ora. Inoltre per ogni corso si specificano le date di inizio e fine del corso, i giorni ,il numero di iscritti al corso, il numero di iscritti abbonati, le ore in cui si effettua il corso ed il costo.
Quindi nella progettazione ho realizzato l'entità iscritto collegata alla relazione frequenta che è collegata con l'entità corso.Le cardinalità sono (0,N) per entrambe le entità.
Quindi ho realizzato le tabelle:

CREATE TABLE iscritto(
codice_fiscale VARCHAR(20) NOT NULL PRIMARY KEY,
data_di_nascita DATE check(YEAR(CURDATE()) - YEAR(data_di_nascita)>18 and YEAR(CURDATE()) - YEAR(data_di_nascita)<90) ,
nome VARCHAR(20) NOT NULL,
cognome VARCHAR(20) NOT NULL,
indirizzo VARCHAR(30) NOT NULL,
costo_abbonamento DECIMAL(10,2),
numero_socio INT NOT NULL,
info_abbonamento VARCHAR(20)
);

CREATE TABLE frequenta(
codice_fiscale_iscritto VARCHAR(20) NOT NULL,
nome_unico_corso VARCHAR(20) NOT NULL,
PRIMARY KEY(codice_fiscale_iscritto,nome_unico_corso)
);

CREATE TABLE corso(
nome_unico VARCHAR(20) NOT NULL PRIMARY KEY,
Descrizione VARCHAR(30) NOT NULL,
sessioni VARCHAR(30) NOT NULL,
codice_istruttore VARCHAR(30) NOT NULL UNIQUE ,
nome_impianto VARCHAR(30) NOT NULL,
Data_inizio DATE,
data_fine DATE,
numero_giorni INT NOT NULL,
numero_iscritti INT,
numero_abbonati INT,
ore INT NOT NULL,
costo DECIMAL(10,2)
);

questo è tutto...

fra85
il vincolo richiesto è :
un corso non può avere più del 20 % di iscritti che non sono abbonati.

Gli altri vincoli erano molto semplici ma questo mi sembra un po difficoltoso...

number15
Non mi hai postato la parte del vincolo dell'80% però :D

Intanto un paio di cose che ti dico tanto per che non inficiano il discorso.
- Per le pk crea sempre un campo int unsigned auto increment (o simili smallint ecc). E' molto più comodo e veloce.
- il check mysql mi pare non lo supporti, forse si postgres (di cui non so nulla :D). Non lo supporta ma non dà errori, quindi concettualmente è giusto e non conosco altri modi (intelligenti) a livello di db per far quel tipo di vincolo.


Per numero iscritti e abbonati hai fatto quindi un trigger che fa +1 ogni volta che qualcuno si iscrive al corso?

Edit: letto ora vincolo.
Ti rispondo

fra85
ok allora se posso,mi consigli di implementare tutto con i check,perchè è troppo difficoltoso con i trigger...

number15
Direi che quel tipo di vincolo non puoi implementarlo con una check.

Allora io farei qualcosa del genere (è delirante).

CREATE TABLE frequenta_temp(
codice_iscritto VARCHAR(20) NOT NULL,
nome_unico_corso VARCHAR(20) NOT NULL,
);

/* il comando di quando vuoi associare un iscritto ad un corso.. */
INSERT INTO frequenta_temp set codice_iscritto = 'xxx', cod_corso = 'xxx';

DELIMITER $$

create trigger temp after insert on frequenta_temp
FOR EACH ROW
BEGIN
IF 0 = (SELECT COUNT(*) FROM frequenta_temp ft, iscritto i WHERE ft.codice_iscritto = i.codice_iscritto AND info_abbonamento = 'iscritto')
THEN
INSERT INTO frequenta set codice_iscritto = NEW.codice_iscritto, nome_unico_corso= NEW.nome_unico_corso;
END IF;

ELSE
IF 0.8 > .... qua devi rapportare numero iscritti + 1 a numero abbonati (scusa, ma son totalmente fuso e non ci capisco + niente... cmq qua fai il caso in cui l'iscritto soddifsca il vincolo)
THEN
INSERT INTO frequenta set codice_iscritto = NEW.codice_iscritto, nome_unico_corso= NEW.nome_unico_corso;
END IF;

TRUNCATE TABLE frequenta_temp;
END$$

DELIMITER ;


Prova a prenderlo come spunto.
Concettualmente dovrebbe andare. Se vuoi stampare il messaggio che non ha inserito perché non rispetta il vincolo, in sql non so come farlo. A quel punto dovresti fare una procedura che ritorna un messaggio, perché i trigger non possono ritornare niente.

prova a vedere un po', nel caso chiedi anche al prof di indicarti la via, perché mi sembra estremamente complesso. Magari loro l'hanno pensato a livello applicativo e a quel punto è semplicsisimo. Controlli prima i valori e se son ok a quel punto permetti di inserire, sennò stampi che non rispetta il vincolo.

Powered by: vbHome (lite) v4.1 and vBulletin v2.3.1 - Copyright ©2000 - 2002, Jelsoft Enterprises Limited
Mantained by dsy crew (email) | Collabora con noi | Segnalaci un bug | Archive | Regolamento |Licenze | Thanks | Syndacate