Visualizzazione dei risultati da 1 a 9 su 9
  1. #1
    Utente di HTML.it L'avatar di TeraBIT
    Registrato dal
    Dec 2005
    Messaggi
    178

    [MySQL] Vincolo intra-relazionale con CHECK [urgentissimo]

    è una cosa stupidissima ma sono alle prime armi e devo finire presto per un esame...


    devo creare un semplice database e inserire in determinate tabelle dei vincoli di integrità sui dati, del tipo se in una tabella c'è una colonna con i voti e l'altra con le lodi non posso inserire un 27 e lode.

    ho provato a usare il costrutto check nelle tabelle che mi serve ma pare che venga completamente ignorato, se faccio uno SHOW CREATE TABLE non compaiono da nessuna parte, come se non li avessi scritti.

    ho provato anche a cambiare la modalità del server in "STRICT" ma non ci sono stati cambiamenti, me lo ingora.
    se ad esempio creo la seguente tabella :
    codice:
    Create table eta (
    Eta	 smallint	 primary key,
    check(Eta>0)
    );
    riesco ugualmente a inserire valori negativi, e se faccio uno SHOW CREATE TABLE eta; il Check non compare da nessuna parte.


    ho la versione 5.0.77 di mysql, ho scandagliato google e alla seguente pagina viene detto che nonostante sia presente nella sintassi non viene realmente implementato(mysql 6.0), allora perchè viene descritto nei libri come costrutto per inserire vincoli di integrità intra-relazionali se poi mysql non li calcola proprio e fà inserire lo stesso dati invalidi senza obbiettare?
    Stò sbagliando io e c'è qualcosa che dovrei fare perchè possano funzionare?

    Altrimenti c'è un modo semplice per inserire dei vincoli intra-relazionali nelle tabelle?
    ho visto che ci sono i trigger ma vanno creati separatamente dalle tabelle e non ho capito benissimo come implementarli nel mio caso...


    confido nel vostro aiuto, non sò più dove sbattere la testa...
    è troppo impegnativo...

  2. #2
    Utente di HTML.it L'avatar di TeraBIT
    Registrato dal
    Dec 2005
    Messaggi
    178
    continuato a cercare in lungo e in largo, mysql il check non lo supporta, ok, ma i trigger hanno una sintassi al quanto complicata e ho bisogno di un piccolo aiuto per capire come scrivere la funzione di controllo...

    mi interessa fare un controllo BEFORE inesert e update, così che non si possano inserire dati incongrui con quanto richiesto dalle colonne interessate (per gli attributi che richiedono l'inserimento di valori predeterminati utilizzerò il dominio ENUM così mi semplifico la vita)


    supponiamo di avere la seguente tabella :

    codice:
    CREATE TABLE tabprova (
    ID             smallint   primary key,
    voto          smallint   not null,
    stato         enum('promosso','bocciato')
    )
    serve un trigger che controlli che quando si inserisce una tupla il valore dell'attributo "stato" sia vincolato a "voto", cioè se voto>18 e si inserisce promosso lo accetta altrimenti rifiuta l'inesritmento/aggiornamento e viceversa, inoltre il valore inserito in "voto" deve essere compreso tra 0 e 30 altrimenti viene rifiutato l'inserimento

    come si scriverebbe il trigger corrispondente?
    è troppo impegnativo...

  3. #3
    Utente di HTML.it L'avatar di clasku
    Registrato dal
    Aug 2006
    Messaggi
    3,197
    Ciao, hai letto questo nelle guide di HTML.IT?
    Nella parte in cui parla della Convalida dei dati.

    Modificandolo un pochino forse puoi risolvere il problema

  4. #4
    Utente di HTML.it L'avatar di TeraBIT
    Registrato dal
    Dec 2005
    Messaggi
    178
    si l'avevo trovato ieri sera, ma lo script serve per approssimare i dati inseriti

    codice:
    IF NEW.prezzo < 0 THEN
    SET NEW.prezzo = 0;
    END IF;
    in pratica corregge l'inserimento, come se mettesse un "valore di default", vorrei invece che l'operazione di inserimento/aggiornamento venisse rifiutata se la condizione non si verifica, come faccio a metterlo in pratica?


    diciamo che nel mio caso servirebbe una cosa del genere :

    codice:
    DELIMITER //
    
    CREATE TRIGGER tabprovaINcheck
    BEFORE INSERT ON tabprova
    FOR EACH ROW
    BEGIN
    
    NEW.voto>0 AND NEW.voto<30
    
    IF NEW.voto>18 AND NEW.stato='bocciato' THEN
    
    rifiutare l'operazione
    
    END IF;
    
    
    IF NEW.voto<18 AND NEW.stato='promosso' THEN
    
    rifiutare l'operazione
    
    END IF;
    
    END; //
    
    
    
    
    
    
    CREATE TRIGGER tabprovaUPcheck
    BEFORE UPDATE ON tabprova
    FOR EACH ROW
    BEGIN
    
    NEW.voto>0 AND NEW.voto<30
    
    IF NEW.voto>18 AND NEW.stato='bocciato' THEN
    
    rifiutare l'operazione
    
    END IF;
    
    
    IF NEW.voto<18 AND NEW.stato='promosso' THEN
    
    rifiutare l'operazione
    
    END IF;
    
    END; //
    
    DELIMITER;

    il problema è proprio che non sò come comporlo sintatticamente, come si scrive "correttamente" questo trigger per far rifiutare l'operazione se non si verifica la condizione? mi basta avere solo questo esempio, i trigger che dovrò inserire sono tutti così...
    è troppo impegnativo...

  5. #5
    Utente di HTML.it L'avatar di nicola75ss
    Registrato dal
    Nov 2004
    Messaggi
    12,923
    @TeraBIT: sei pregato di leggerti il regolamento e di evitare nel titolo parole inutili come urgentissimo visto che nessun thread ha priorità su altri. Per questa volta mi limito a modificarlo io e non ti chiudo la discussione. In futuro presta più attenzione.

  6. #6
    Utente di HTML.it L'avatar di clasku
    Registrato dal
    Aug 2006
    Messaggi
    3,197
    non so come si faccia a rifiutare l'operazione, bisognerebbe capire il comportamento se si pongono solo alcune condizioni...
    tipo questo:
    codice:
    DELIMITER //
    
    CREATE TRIGGER tabprovaINcheck
    BEFORE INSERT ON tabprova
    FOR EACH ROW
    BEGIN
    
    IF
    NEW.voto>0 AND NEW.voto<30
    SET NEW.voto = "il valore che passi alla query (forse potrebbe essere anche un NEW.voto=New.voto)" 
    END IF;
    
    IF NEW.voto>18 AND NEW.stato='promosso' THEN
    SET NEW.voto = "il valore che passi alla query (forse potrebbe essere anche un NEW.voto=New.voto)" 
    SET NEW.stato = 'promosso'
    END IF;
    
    IF NEW.voto<18 AND NEW.stato='bocciato' THEN
    SET NEW.voto = "il valore che passi alla query (forse potrebbe essere anche un NEW.voto=New.voto)" 
    SET NEW.stato = 'bocciato'
    END IF;
    
    END; //
    Fai un paio di prove

  7. #7
    Utente di HTML.it L'avatar di TeraBIT
    Registrato dal
    Dec 2005
    Messaggi
    178
    ho ottenuto un risultato, sono riuscito a creare un trigger funzionante :

    codice:
    -- Trigger DDL Statements
    USE DatabaseSQL;
    DELIMITER //
    
    CREATE TRIGGER tabprovaINcheck
    BEFORE INSERT ON tabprova
    FOR EACH ROW BEGIN
    
    IF
    NEW.voto > 30 THEN
    SET NEW.voto = null;
    END IF;
    
    IF
    NEW.voto > 18 AND NEW.stato = 'bocciato' THEN
    SET NEW.voto = null;
    END IF;
    
    END;
    //
    in questo modo se inserisco un voto maggiore di 30 viene predisposto un null, ma siccome il null non viene accettato come valore nella colonna l'inserimento viene annullato, stessa cosa se il voto è maggiore di 18 e viene inserito lo stato 'bocciato', ma è solo un trucco subdolo, ci sarà un comando da mettere dopo il 'THEN' che impedisca l'inserimento senza vincolare gli attributi con un not null...

    vorrei che la command line specificasse che i dati inseriti sono scorretti, non che non è possibile inserire un valore null nell'attributo X (valore che viene messo dal trigger)
    è troppo impegnativo...

  8. #8
    Utente di HTML.it L'avatar di TeraBIT
    Registrato dal
    Dec 2005
    Messaggi
    178
    nella wiki viene detto quanto segue

    MySQL handles errors during trigger execution as follows:

    * if a BEFORE trigger fails, the operation on the corresponding row is not performed.

    * a BEFORE trigger is activated by the attempt to insert or modify the row, regardless of
    whether the attempt subsequently succeeds.

    è esattamente ciò che mi serve, in che modo il BEFORE fallisce? Fa rifermento alle condizioni (statement) inserite nel trigger o a un errore di esecuzione dello stesso? il secondo punto lascia trasparire la possibilità di rifiutare l'operazione, ma ho il sospetto che si riferisca al "trucco" che ho usato io (un valore null che annulla l'operazione)...
    è troppo impegnativo...

  9. #9
    Utente di HTML.it L'avatar di TeraBIT
    Registrato dal
    Dec 2005
    Messaggi
    178
    pare non ci sia un modo esplicito per fare rifiutare un inserimento, o perlomeno non ne ho trovato uno, poco male, vorrà dire che usero questo sistema per far evitare l'inserimento di una riga al verificarsi di determinate condizioni, semplicemente facendo impostare (SET) come null un valore che non deve esserlo (ad esempio la primary key), l'effetto è comunque quello
    è troppo impegnativo...

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.