質問

一貫性の理由で、関係のある関係の列を変更できないようにしたいと思います。

バックストーリーは、「接続」関係に追加の値がある:n関係があるということです。誰もが関係パートナーのIDを変更できることを望んでいません。

私がこれまでに思いついたこと:

新しい値が古い値と同じかどうかをチェックするトリガーを作成します。しかし、条件が真実であると証明された場合、更新アクションを拒否する方法がわかりません。

これがこれまでの私のトリガーです:

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;
役に立ちましたか?

解決

更新を中止するのではなく、それを無効にしますか?

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

他のヒント

読みやすいエラーメッセージを中止および返すためのかなり素晴らしくてきれいな方法は、信号を使用することです。

Signal SqlState '45000' set message_text = 'schueler_idおよびklasse_idは変更されない場合があります!';

MySQLバージョンがこれをサポートしていることを確認してください。MySQL5.5で導入されました。以前のバージョンでは、存在しないフィールドを存在しないテーブルに挿入するなど、ハッキングが必要です。

GBNが言及しているように、新しい値を古い値で上書きすることも良い選択肢です。

私は実際にトリガーを中止するためのバックアリーアプローチを学びました. 。これは非常に粗雑ですが、信号処理がMySQLのストアドプロシージャ言語に実装されていないため機能します。せいぜいエミュレートできます。

第11章、本の254〜256ページ MySQLストアドプロシージャプログラミング サブヘディングの下 「トリガーによるデータの検証」 文字文字列をダミー整数に選択することを提案します(構文の観点からは正しいが、実行中に死ぬ[しゃれも意図しない]):

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; 

INNODBを使用している場合、トリガーを使用せずにこれをきれいに行うことが実際に可能です。

たった1つの列で別のテーブルを作成します。その列には、問題の元のテーブルの不変の列を指す外部キー(したがって、このソリューションのINNODB要件)が必要です。

「更新制限」などの制限を設定します。

要約すれば:

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;

私が読んだすべての答えの組み合わせに基づいて、これは私のために働いたものです:

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
ライセンス: CC-BY-SA帰属
所属していません dba.stackexchange
scroll top