เป็นไปได้ไหมที่จะสร้างหนึ่งคอลัมน์แบบอ่านอย่างเดียว?


25

ฉันอยากรู้ว่าเป็นไปได้ไหมที่จะสร้างตารางที่มีคอลัมน์ที่ไม่สามารถเปลี่ยนแปลงได้ แต่คอลัมน์อื่น ๆ ของตารางสามารถทำได้

เช่นฉันสามารถจินตนาการCreatedByUserคอลัมน์ที่ไม่ควรเปลี่ยนแปลง

มีฟังก์ชันในตัวใน SQL Server สำหรับสิ่งนี้หรือเป็นไปได้เฉพาะผ่านทางทริกเกอร์หรืออย่างอื่นเท่านั้น


ฉันไม่เชื่อว่ามีวิธีอื่นนอกเหนือจากการใช้ทริกเกอร์และอนุญาตเฉพาะการสร้าง / อัพเดต / ลบคำสั่งผ่านขั้นตอน
Mark S. Rasmussen


@ MartinSmith ขอบคุณสำหรับลิงก์ ฉันเดาว่าจะเป็นคำตอบสำหรับคำถามของฉัน ดังนั้นให้คำตอบและฉันจะยอมรับมัน
Philipp M

คำตอบ:


19

ไม่มีการสร้างขึ้นในการสนับสนุนที่ประกาศสำหรับคอลัมน์ที่ไม่สามารถอัปเดตได้ (ยกเว้นกรณีที่กำหนดไว้ล่วงหน้าเช่นIDENTITY)

รายการเชื่อมต่อนี้ร้องขอ แต่ถูกปฏิเสธ เพิ่ม DRI เพื่อบังคับใช้ค่าคอลัมน์ที่ไม่เปลี่ยนรูป

UPDATEทริกเกอร์อาจจะเป็นวิธีที่มีประสิทธิภาพมากที่สุดในการบรรลุเป้าหมายนี้ สามารถตรวจสอบIF UPDATE(CreatedByUser)และเพิ่มข้อผิดพลาดและย้อนกลับการทำธุรกรรมได้หากเป็นจริง


ลิงก์ Archive.org ไปยังรายการคำขอเชื่อมต่อเก่าที่ลิงก์ด้านบน: web.archive.org/web/20130402211121/http://connect.microsoft.com/?id
Anssssss

7

ฉันได้ดำเนินการตามUPDATE TRIGGERแนวทางที่เสนอโดยคำตอบของ Martin Smithดังนี้

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     

(หมายเหตุ: ตารางมีคอลัมน์คีย์หลักที่เรียกว่า ID)

ฉันจะปฏิเสธการอัปเดตหากมูลค่าของ AssetTypeID เปลี่ยนไปเท่านั้น ดังนั้นคอลัมน์อาจมีอยู่ในการอัปเดตและหากค่าไม่เปลี่ยนแปลงกว่าที่มันจะผ่าน (ฉันต้องการวิธีนี้)


1
หากมีการบันทึกเฉพาะการAssetTypeIDตั้งค่าเป็นค่าที่ไม่ใช่ศูนย์และคุณเรียกใช้UPDATE Asset SET AssetTypeID = NULL WHERE Asset = the_idที่จะไม่มีการย้อนกลับเพราะWHERE i.AssetTypeID <> d.AssetTypeIDในทริกเกอร์จะประเมินเป็นเท็จออกจากคอลัมน์ที่สามารถแก้ไขได้
Christiaan Westerbeek

3

คุณสามารถใช้มุมมองกับคอลัมน์ที่ได้รับ ลองสิ่งนี้

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;

ฉันไม่แน่ใจว่าคุณหมายถึงอะไร คุณสามารถทำอย่างละเอียด?
Philipp M

แต่คุณสามารถอัปเดตตารางและเปลี่ยนค่าได้
Philipp M

1
@Phippipp M แต่คุณสามารถเพิกถอนการเข้าถึงตารางและให้สิทธิ์การดู ไม่มัน
msi77

-3

เหตุใดคุณจึงอัปเดตคอลัมน์ที่สร้างโดย

ฉันจะมีสองคอลัมน์ [created_by] และ [modified_by] คอลัมน์ที่ส่วนแทรกแรกจะแทรกคอลัมน์ตามลำดับทั้งหมดในบันทึกและการปรับปรุงใด ๆ ที่ตามมาจะอัพเดตคอลัมน์ [modified_by] (ผ่านทริกเกอร์ในแอปพลิเคชัน เลเยอร์คุณสามารถจัดโครงสร้างการอัปเดตเพื่อเปลี่ยน [modified_by] พร้อมกับคอลัมน์ที่เกี่ยวข้องของคุณ)


3
ฉันคิดว่าคุณพลาดประเด็นไปแล้ว มีการถามว่ามีการสนับสนุนใด ๆ ที่สร้างขึ้นเพื่อบังคับใช้อย่างแม่นยำหรือไม่ว่าคอลัมน์ไม่ควรอัปเดตได้
Martin Smith

@MartinSmith แน่นอน - เรามีคอลัมน์ที่ถูกแก้ไขเช่นกันและฉันก็แค่อยากรู้ว่ามีอยู่แล้วในการสนับสนุนสำหรับอ่านอย่างเดียวอยู่แล้ว
Philipp M
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.