Có thể làm cho một cột chỉ đọc?


25

Tôi tò mò liệu có thể tạo một bảng với một cột không bao giờ có thể thay đổi, nhưng các cột khác của bảng có thể.

Ví dụ, tôi có thể tưởng tượng một CreatedByUsercột không bao giờ nên thay đổi.

Có một chức năng tích hợp trong SQL Server cho việc này không, hay chỉ có thể thông qua các trình kích hoạt hoặc một cái gì khác?


Tôi không tin có bất kỳ cách nào khác ngoài việc thực hiện các kích hoạt và chỉ cho phép tạo / cập nhật / xóa các câu lệnh thông qua các thủ tục.
Đánh dấu S. Rasmussen


@MartinSmith cảm ơn, vì đường link. Tôi đoán đó sẽ là câu trả lời cho câu hỏi của tôi. Vì vậy, làm cho nó một câu trả lời và tôi sẽ chấp nhận nó.
Philipp M

Câu trả lời:


19

Không có hỗ trợ khai báo được xây dựng cho các cột không cập nhật (ngoại trừ các trường hợp được xác định trước cụ thể như IDENTITY)

Mục Connect này đã yêu cầu nhưng bị từ chối. Thêm DRI để thực thi các giá trị cột bất biến

Một UPDATEkích hoạt có lẽ sẽ là cách mạnh mẽ nhất để đạt được điều này. Nó có thể kiểm tra IF UPDATE(CreatedByUser)và đưa ra một lỗi và phục hồi giao dịch nếu đúng.


Archive.org liên kết tới mục yêu cầu cũ Connect liên kết ở trên: web.archive.org/web/20130402211121/http://connect.microsoft.com/...
Anssssss

7

Tôi đã thực hiện UPDATE TRIGGERphương pháp tiếp cận được đề xuất bởi câu trả lời của Martin Smith như sau:

CREATE TRIGGER trgAfterUpdateAsset ON dbo.Asset
FOR UPDATE AS
IF UPDATE(AssetTypeID) AND EXISTS (SELECT * FROM inserted i JOIN deleted d ON i.ID = d.ID WHERE i.AssetTypeID <> d.AssetTypeID)
BEGIN 
    RAISERROR ('AssetTypeID cannot change.', 16, 1);
    ROLLBACK TRAN
END     

(Lưu ý: Bảng có cột Khóa chính, được gọi là ID).

Tôi chỉ từ chối cập nhật nếu giá trị của AssetTypeID thay đổi. Vì vậy, cột có thể có mặt trong một bản cập nhật và nếu giá trị không thay đổi, thì nó sẽ đi qua. (Tôi cần cách này)


1
Nếu đối với một bản ghi cụ thể, AssetTypeIDnó được đặt thành giá trị khác null và bạn chạy UPDATE Asset SET AssetTypeID = NULL WHERE Asset = the_idrằng sẽ không có rollback vì WHERE i.AssetTypeID <> d.AssetTypeIDtrong trình kích hoạt sẽ đánh giá thành false, để cột đó có thể chỉnh sửa.
Christiaan Westerbeek

3

Bạn có thể sử dụng một khung nhìn với cột dẫn xuất. Thử đi

create table ro_test(id int primary key, CreatedByUser int)
go
create view v_ro_test
as
select id, CreatedByUser*1 CreatedByUser from ro_test
go

insert into ro_test values(1,10);
update ro_test
set CreatedByUser =11
where id =1;
select * from v_ro_test;
go
--ERROR--
update v_ro_test
set CreatedByUser =10
where id =1;

--BUT--
update v_ro_test
set id =2
where id =1;
select * from v_ro_test;

Tôi không chắc ý của bạn là gì. Bạn có thể xây dựng?
Philipp M

Nhưng bạn chỉ có thể cập nhật bảng và thay đổi giá trị của nó
Philipp M

1
@Philipp M Nhưng bạn có thể thu hồi quyền truy cập vào bảng và cấp cho chế độ xem. Phải vậy không?
msi77

-3

Tại sao bạn cập nhật cột createdby?

Tôi sẽ có hai cột một cột [created_by] và cột [mod_by], trong đó lần chèn đầu tiên sẽ chèn tất cả các cột tương ứng trong bản ghi và mọi cập nhật tiếp theo sẽ chỉ cập nhật cột [mod_by] (thông qua trình kích hoạt trong ứng dụng lớp bạn có thể cấu trúc bản cập nhật của mình để chỉ thay đổi [mod_by], cùng với các cột tương ứng của bạn)


3
Tôi nghĩ rằng bạn đã bỏ lỡ điểm của câu hỏi. Đó là hỏi liệu có bất kỳ hỗ trợ tích hợp nào để thực thi chính xác rằng cột không nên cập nhật được không .
Martin Smith

@MartinSmith Chính xác - chúng tôi cũng có một cột được sửa đổi và tôi chỉ tò mò về việc liệu có hỗ trợ tích hợp cho sự tồn tại chỉ đọc hay không
Philipp M
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.