Domanda

Voglio fare una colonna in un rapporto unmodifyable per motivi di coerenza.

Il retroscena è che ho un n: n rapporto in cui la relazione "collegamento" ha valori aggiuntivi. Non voglio che chiunque è in grado di cambiare gli ID dei partner di relazione.

Quello che ho messo a punto finora:

La creazione di un trigger che controlla se il nuovo valore è uguale al vecchio valore. Ma io non so come negare l'azione UPDATE se la condizione si rivela come VERO.

Ecco il mio grilletto finora:

CREATE TRIGGER deny_nton_change BEFORE UPDATE ON Schueler_in_Klasse
FOR EACH ROW BEGIN
    IF NEW.Schueler_ID != OLD.Schueler_ID OR NEW.Klasse_ID != OLD.Klasse_ID THEN

    END IF;
END;
È stato utile?

Soluzione

Piuttosto che abortire l'aggiornamento, basta ignorare vero?

...
FOR EACH ROW BEGIN
    SET NEW.Schueler_ID = OLD.Schueler_ID;
    SET NEW.Klasse_ID = OLD.Klasse_ID;
END

Altri suggerimenti

Un modo abbastanza bello e pulito per annullare e restituire un messaggio di errore leggibile è quello di utilizzare un segnale:

SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Schueler_ID e Klasse_ID non possono essere modificate!';

Facciamo in modo la versione di MySQL sostiene questo, è stato introdotto in MySQL 5.5. Nelle versioni precedenti è necessario hack come l'inserimento di un campo inesistente in una tabella inesistente.

Come gbn menziona, sovrascrivendo i nuovi valori con quelli vecchi è una buona opzione troppo.

realtà ho imparato un approccio back-vicolo per abortire trigger . E 'molto grezzo, ma funziona perché l'elaborazione del segnale non è implementata in stored procedure Lingua di MySQL. Si può essere emulato al meglio.

Capitolo 11, pagine 254-256 del libro MySQL Stored Procedura di programmazione il sottotitolo 'dati Convalida con trigger' suggerisce fare un SELECT di una stringa di caratteri in un intero fittizio (in termini di sintassi, è corretto, ma stampi sullo esecuzione [NO gioco di parole]):

CREATE TRIGGER deny_nton_change BEFORE UPDATE ON Schueler_in_Klasse 
FOR EACH ROW BEGIN
    DECLARE dummy INT; 
    IF NEW.Schueler_ID != OLD.Schueler_ID OR NEW.Klasse_ID != OLD.Klasse_ID THEN 
        SELECT 'Cannot Carry Out This Trigger Any Further'
        INTO dummy FROM table_you_know_does_not_exist WHERE 1=1 LIMIT 1;
    END IF; 
END; 

In realtà è possibile farlo ordinatamente senza l'utilizzo di trigger se si utilizza InnoDB.

Crea un altro tavolo con una sola colonna. Tale colonna deve avere una chiave esterna (qui la necessità innodb in questa soluzione) che punta alla colonna immutabile della tabella originale in questione.

Mettere una restrizione del tipo "ON UPDATE Vieta".

In sintesi:

CREATE TABLE original (
     ....
     immutable_column ...
     INDEX index1(immutable_column)
     ....
) ENGINE=INNODB;

CREATE TABLE restricter (
     .....
     col1,
     INDEX index2(col1),
     FOREIGN KEY (col1) REFERENCES original (immutable_colum) ON UPDATE RESTRICT ON DELETE CASCADE
) ENGINE=INNODB;

In base a una combinazione di tutte le risposte che ho letto questo è ciò che ha funzionato per me:

delimiter $$ -- You may need this or not (in my visual client I need it, directly in console I don't)
create trigger deny_nton_change before update on surveys
for each row begin
    if new.Schueler_ID != old.Schueler_ID OR new.Klasse_ID != old.Klasse_ID then
      signal sqlstate '45000' set message_text = 'My own Error: Field is immutable';
    end if;
end$$
delimiter ; -- You may need this or not
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a dba.stackexchange
scroll top