36

テーブルに (これまでに) 変更したくない行があります。

MySQL の行を READ-ONLY に設定して、更新できないようにすることはできますか? もしそうなら、どのように?

そうでない場合、その行のいずれかの列に永続的な値を設定して、変更できないようにすることは可能ですか? もしそうなら、どのように?

ありがとう。

4

1 に答える 1

41

これはビジネス ロジックである可能性が高く、おそらくデータ ストレージ レイヤーには属していません。ただし、それでもトリガーを使用して実現できます。

BEFORE UPDATE「ロックされた」レコードが更新されようとしている場合にエラーを発生させるトリガーを作成できます。操作が開始される前にエラーが発生するため、MySQL は操作を中止します。レコードが削除されないようにする場合は、同様のトリガーを作成する必要がありますBEFORE DELETE

レコードが「ロックされている」かどうかを判断するには、ブールlocked列を作成できます。

ALTER TABLE my_table ADD COLUMN locked BOOLEAN NOT NULL DEFAULT FALSE;

DELIMITER ;;

CREATE TRIGGER foo_upd BEFORE UPDATE ON my_table FOR EACH ROW
IF OLD.locked THEN
  SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Cannot update locked record';
END IF;;

CREATE TRIGGER foo_del BEFORE DELETE ON my_table FOR EACH ROW
IF OLD.locked THEN
  SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Cannot delete locked record';
END IF;;

DELIMITER ;

UPDATE my_table SET locked = TRUE WHERE ...;

SIGNALMySQL 5.5 で導入されたことに注意してください。以前のバージョンでは、MySQL でエラーが発生する原因となる誤ったアクションを実行する必要があります。CALL raise_error;


このテーブルに追加の列を作成することはできませんが、行の列の 1 つに一意の ID があるため、そのシナリオでこれを行うにはどうすればよいですか?

繰り返しになりますが、このロジックを絶対にストレージ レイヤーに配置する必要があり、PK 以外の方法でロックされたレコードを識別できない場合は、テストをトリガーにハードコーディングできます。たとえば、レコードを「ロック」するにはid_column = 1234:

DELIMITER ;;

CREATE TRIGGER foo_upd BEFORE UPDATE ON my_table FOR EACH ROW
IF OLD.id_column <=> 1234 THEN
  SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Cannot update locked record';
END IF;;

CREATE TRIGGER foo_del BEFORE DELETE ON my_table FOR EACH ROW
IF OLD.id_column <=> 1234 THEN
  SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Cannot delete locked record';
END IF;;

DELIMITER ;

しかし、これは絶対に恐ろしいことであり、可能な限りそれを避けるために私はほとんど何でもします.

于 2012-05-08T16:12:40.047 に答える