2012-05-08 34 views
31

Tôi có một hàng trong một bảng mà tôi không muốn bị thay đổi (bao giờ).Cách đặt hàng MySQL thành READ-ONLY?

Có thể đặt hàng MySQL thành READ-ONLY sao cho nó không thể được cập nhật theo bất kỳ cách nào? Nếu vậy, làm thế nào?

Nếu không, có thể đặt giá trị cố định ở một trong các cột của hàng đó sao cho nó không thể thay đổi được không? Nếu vậy, làm thế nào?

Cảm ơn.

+3

Không, không có thứ gì như hàng chỉ đọc. Nhưng bạn có thể thiết lập các tài khoản MySQL sao cho một người dùng cụ thể không có quyền cập nhật/xóa. –

+0

Poss dup: http://stackoverflow.com/questions/3878672/how-to-lock-particular-row-in-mysql –

+0

@Marc B: Vì vậy, không phải tùy chọn nào tôi đề cập đều có sẵn? Vui lòng xác nhận, vì giải pháp quyền người dùng mà bạn đề cập sẽ không giải quyết được sự cố của tôi. – ProgrammerGirl

Trả lời

34

Đây có thể là logic nghiệp vụ, có thể không thuộc về lớp lưu trữ dữ liệu của bạn. Tuy nhiên, nó có thể được thực hiện bằng cách sử dụng triggers.

Bạn có thể tạo trình kích hoạt BEFORE UPDATE gây ra lỗi nếu bản ghi "bị khóa" sắp được cập nhật; vì lỗi xảy ra trước khi hoạt động của được thực hiện, MySQL không còn tiếp tục. Nếu bạn cũng muốn ngăn không cho xóa bản ghi, bạn cần tạo một trình kích hoạt tương tự BEFORE DELETE.

Để xác định xem mức kỷ lục là "khóa", bạn có thể tạo một locked cột boolean:

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 ...; 

Lưu ý rằng SIGNAL đã được giới thiệu trong MySQL 5.5. Trong các phiên bản trước, bạn phải thực hiện một số hành động sai khiến MySQL gây ra lỗi: Tôi thường gọi thủ tục không tồn tại, ví dụ: với CALL raise_error;


I cannot create an additional column on this table, but the row has a unique id in one of the columns, so how would I do this for that scenario?

Một lần nữa, nếu bạn hoàn toàn phải nơi logic này trong việc lưu trữ lớp và không thể xác định các hồ sơ khóa thông qua bất kỳ phương tiện khác ngoài PK-bạn thể cứng mã kiểm tra kích hoạt của bạn; ví dụ, để "khóa" các kỷ lục với 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 ; 

Nhưng điều này là hoàn toàn khủng khiếp và tôi sẽ làm hầu hết mọi thứ để tránh nó bất cứ khi nào có thể.

+0

Cảm ơn một giải pháp rất thú vị. Tôi không thể tạo một cột bổ sung trên bảng này, nhưng hàng có một id duy nhất trong một trong các cột, vì vậy làm thế nào tôi sẽ làm điều này cho kịch bản đó? – ProgrammerGirl

+0

@Programmer: Chỉ cần kiểm tra trên 'id' trong câu lệnh' IF' của trigger: 'IF OLD.column <=> 'unique_id' THEN ...'. – eggyal

+2

Bây giờ có một giải pháp không chính thống. Tôi thích nó. 1 giữ trong tâm trí mặc dù rằng bạn chỉ có thể có một kích hoạt (mỗi sự kiện cho mỗi bảng) trong mysql vì vậy nếu bạn đã có hoặc cần một kích hoạt khác trong tương lai ... bạn phải kết hợp chúng thành một. – Kris

Các vấn đề liên quan