É possível criar uma coluna somente leitura?

25

Estou curioso para saber se é possível criar uma tabela com uma coluna que nunca pode ser alterada, mas as outras colunas da tabela podem.

Por exemplo, eu poderia imaginar uma CreatedByUsercoluna que nunca deveria ser alterada.

Existe uma funcionalidade interna no SQL Server para isso, ou é possível apenas através de gatilhos ou outra coisa?

Philipp M
fonte
Não acredito que exista outra maneira de implementar gatilhos e apenas permitir criar / atualizar / excluir instruções por meio de procedimentos.
Mark S. Rasmussen
Obrigado Martin, pelo link. Eu acho que essa seria a resposta para minha pergunta. Então faça uma resposta e eu aceito.
Philipp M

Respostas:

19

Não há suporte declarativo embutido para colunas não atualizáveis ​​(exceto casos específicos predefinidos, como IDENTITY)

Este item do Connect solicitou, mas foi rejeitado. Adicione DRI para aplicar valores imutáveis ​​da coluna

Um UPDATEgatilho provavelmente seria a maneira mais robusta de conseguir isso. Ele poderia verificar IF UPDATE(CreatedByUser)e gerar um erro e reverter a transação, se verdadeira.

Martin Smith
fonte
Link do Archive.org para o item de solicitação antigo do Connect vinculado acima: web.archive.org/web/20130402211121/http://connect.microsoft.com/…
Anssssss
7

Fiz minha implementação da UPDATE TRIGGERabordagem sugerida pela resposta de Martin Smith da seguinte maneira:

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     

(Nota: a tabela possui uma coluna Chave Primária, chamada ID).

Só rejeito a atualização se o valor de AssetTypeID for alterado. Portanto, a coluna pode estar presente em uma atualização e, se o valor não for alterado, ele passará. (Eu precisava desse jeito)

jaraics
fonte
11
Se, para um registro específico, ele AssetTypeIDestiver definido como um valor não nulo e você executar UPDATE Asset SET AssetTypeID = NULL WHERE Asset = the_idque não haveria reversão, porque WHERE i.AssetTypeID <> d.AssetTypeIDo gatilho seria avaliado como falso, deixando a coluna editável.
Christiaan Westerbeek 21/03
3

Você pode usar uma visualização com coluna derivada. Tente isto

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;
msi77
fonte
Não sei bem o que você quer dizer. Você pode elaborar?
Philipp Philipp
Mas você pode apenas atualizar a tabela e alterar seus valores
Philipp M
11
@ Philipp M Mas você pode revogar o acesso à tabela e conceder à exibição. Não é?
msi77
-3

Por que você está atualizando a coluna createdby?

Eu teria duas colunas, uma coluna [created_by] e [modified_by], em que a primeira inserção inseria todas as colunas respectivas no registro, e quaisquer atualizações subsequentes apenas atualizariam a coluna [modified_by] (por meio de um gatilho no aplicativo camada, você pode estruturar sua atualização para alterar somente o [modified_by], juntamente com suas respectivas colunas)

apachebeard
fonte
3
Eu acho que você perdeu o ponto da questão. Ele estava perguntando se havia algum suporte interno para impor com precisão que a coluna não fosse atualizável.
Martin Smith
@MartinSmith Exatamente - Nós temos uma coluna modificada bem e eu só estava curioso sobre se um suporte embutido para somente leitura existe
Philipp M