是否可以将一列设为只读?


25

我很好奇是否可以用无法更改的列创建表,但表的其他列可以更改。

例如,我可以想象一个CreatedByUser永远不应该更改的列。

SQL Server是否为此提供了内置功能,还是只能通过触发器或其他方式实现?


除了实现触发器并仅允许通过过程创建/更新/删除语句外,我认为没有其他方法可以解决此问题。
Mark S. Rasmussen


@MartinSmith,谢谢您的链接。我想那将是我的问题的答案。因此,将其作为答案,我会接受的。
Philipp M

Answers:


19

对于不可更新的列,没有内置的声明式支持(特定的预定义情况除外,例如IDENTITY

此连接项已请求它,但被拒绝。添加DRI以强制使用不可变的列值

一个UPDATE触发很可能是实现这一目标的最可靠的方法。它可能会检查IF UPDATE(CreatedByUser)并引发错误,如果为true,则回滚事务。


Archive.org链接到上面链接的旧的Connect请求项:web.archive.org/web/20130402211121/http
//connect.microsoft.com/…– Anssssss

7

我已经实现UPDATE TRIGGER马丁·史密斯的答案所建议的方法,如下所示:

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设置为非null值,并且您运行了UPDATE Asset SET AssetTypeID = NULL WHERE Asset = the_id该操作,则不会进行回滚,因为WHERE i.AssetTypeID <> d.AssetTypeID在触发器中,该求值将为false,从而使该列可编辑。
克里斯蒂安·韦斯特贝克

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
@Philipp M但是您可以撤消对该表的访问并将其授予视图。不是吗
msi77 2013年

-3

为什么要更新createdby列?

我将有两列[created_by]和[modified_by]列,其中第一个插入将在记录中插入所有相应的列,而任何后续更新将只更新[modified_by]列(通过应用程序中的触发器层,您可以将更新结构化为仅更改[modified_by]以及相应的列)


3
我认为您错过了问题的重点。有人问是否有任何内置支持正是执行这一栏应该不是可更新。
马丁·史密斯

@MartinSmith确实-我们的确也有一个修改过的专栏,我只是很好奇是否存在对只读的内置支持
Philipp M
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.