Apakah mungkin membuat satu kolom hanya bisa dibaca?


25

Saya ingin tahu apakah mungkin untuk membuat tabel dengan kolom yang tidak pernah bisa diubah, tetapi kolom lain dari tabel bisa.

Misalnya saya bisa membayangkan CreatedByUserkolom yang tidak boleh diubah.

Apakah ada fungsi built-in di SQL Server untuk ini, atau hanya mungkin melalui pemicu atau yang lainnya?


Saya tidak percaya ada cara lain selain menerapkan pemicu dan hanya memungkinkan membuat / memperbarui / menghapus pernyataan melalui prosedur.
Mark S. Rasmussen


@ MartinSmith terima kasih, untuk tautannya. Saya kira itu akan menjadi jawaban untuk pertanyaan saya. Jadi buatlah jawaban dan saya akan menerimanya.
Philipp M

Jawaban:


19

Tidak ada dukungan deklaratif bawaan untuk kolom yang tidak dapat diperbarui (kecuali untuk kasus tertentu yang ditentukan sebelumnya seperti IDENTITY)

Item Connect ini memintanya tetapi ditolak. Tambahkan DRI untuk memberlakukan nilai kolom yang tidak dapat diubah

Sebuah UPDATEpemicu mungkin akan menjadi cara yang paling kuat untuk mencapai ini. Itu bisa memeriksa IF UPDATE(CreatedByUser)dan meningkatkan kesalahan dan mengembalikan transaksi jika benar.


Tautan Archive.org ke item permintaan Connect lama yang ditautkan di atas: web.archive.org/web/20130402211121/http
Anssssss

7

Saya telah membuat implementasi UPDATE TRIGGERpendekatan yang disarankan oleh jawaban Martin Smith sebagai berikut:

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     

(Catatan: Tabel ini memiliki kolom Kunci Utama, yang disebut ID).

Saya hanya menolak pembaruan jika nilai perubahan AssetTypeID. Jadi kolom bisa hadir dalam pembaruan, dan jika nilainya tidak berubah, maka akan melewati. (Saya butuh cara ini)


1
Jika untuk catatan tertentu AssetTypeIDdiatur ke nilai non-nol dan Anda menjalankan UPDATE Asset SET AssetTypeID = NULL WHERE Asset = the_idbahwa tidak akan ada kembalikan karena WHERE i.AssetTypeID <> d.AssetTypeIDdalam pemicu akan mengevaluasi menjadi salah, meninggalkan kolom yang dapat diedit.
Christiaan Westerbeek

3

Anda bisa menggunakan tampilan dengan kolom turunan. Coba ini

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;

Saya tidak yakin apa yang Anda maksud. Bisakah Anda menguraikan?
Philipp M

Tapi Anda bisa memperbarui tabel dan mengubah nilainya
Philipp M

1
@ Pilip M Tapi Anda bisa mencabut akses ke tabel dan memberikannya ke tampilan. Iya kan?
msi77

-3

Mengapa Anda memperbarui kolom yang dibuat oleh?

Saya akan memiliki dua kolom, kolom [Created_by] dan [modified_by], di mana sisipan pertama akan menyisipkan semua kolom masing-masing dalam catatan, dan setiap pembaruan berikutnya hanya akan memperbarui kolom [modified_by] (melalui pemicu pada aplikasi. layer Anda dapat menyusun pembaruan hanya mengubah [modified_by], beserta kolom Anda masing-masing)


3
Saya pikir Anda telah melewatkan inti pertanyaan. Itu bertanya apakah ada dukungan dibangun untuk menegakkan secara tepat bahwa kolom tidak boleh diperbarui.
Martin Smith

@ MartinSmith Persis - kami memiliki kolom yang dimodifikasi juga dan saya hanya ingin tahu apakah ada dukungan bawaan untuk readonly
Philipp M
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.