¿Es posible hacer una columna de solo lectura?


25

Tengo curiosidad por saber si es posible crear una tabla con una columna que nunca se pueda cambiar, pero las otras columnas de la tabla sí.

Por ejemplo, podría imaginar una CreatedByUsercolumna que nunca debería cambiarse.

¿Existe una funcionalidad incorporada en SQL Server para esto, o solo es posible a través de disparadores u otra cosa?


No creo que haya otra forma de evitar esto que no sea implementar disparadores y solo permitir crear / actualizar / eliminar declaraciones a través de procedimientos.
Mark S. Rasmussen


@ MartininSmith gracias, por el enlace. Supongo que esa sería la respuesta a mi pregunta. Así que responda y lo aceptaré.
Philipp M

Respuestas:


19

No hay soporte declarativo integrado para columnas no actualizables (excepto para casos predefinidos específicos como IDENTITY)

Este elemento de Connect lo solicitó pero fue rechazado. Agregue DRI para aplicar valores de columna inmutables

Un UPDATEdisparador probablemente sería la forma más sólida de lograr esto. Podría verificar IF UPDATE(CreatedByUser)y generar un error y revertir la transacción si es verdadero.


Enlace de Archive.org al antiguo elemento de solicitud de Connect vinculado anteriormente: web.archive.org/web/20130402211121/http://connect.microsoft.com/…
Anssssss

7

He implementado el UPDATE TRIGGERenfoque sugerido por la respuesta de Martin Smith de la siguiente manera:

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: La tabla tiene una columna de Clave primaria, llamada ID).

Solo estoy rechazando la actualización si el valor de AssetTypeID cambia. Entonces, la columna podría estar presente en una actualización, y si el valor no cambiara, entonces pasaría. (Lo necesitaba de esta manera)


1
Si para un registro particular, AssetTypeIDse establece en un valor no nulo y se ejecuta, UPDATE Asset SET AssetTypeID = NULL WHERE Asset = the_idno habrá reversión porque WHERE i.AssetTypeID <> d.AssetTypeIDen el desencadenador se evaluaría como falso, dejando esa columna editable.
Christiaan Westerbeek

3

Puede usar una vista con columna derivada. Prueba esto

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;

No estoy seguro de lo que quieres decir. ¿Puedes elaborar?
Philipp M

Pero solo puede actualizar la tabla y cambiar sus valores
Philipp M

1
@Philipp M Pero puede revocar el acceso a la tabla y otorgarlo a la vista. ¿No lo hace?
msi77

-3

¿Por qué estás actualizando la columna createdby?

Tendría dos columnas una columna [created_by] y una [modified_by], donde la primera inserción insertaría todas las columnas respectivas en el registro, y cualquier actualización posterior solo actualizaría la columna [modified_by] (a través de un activador en la aplicación capa puede estructurar su actualización para cambiar solo el [modificado_por], junto con sus respectivas columnas)


3
Creo que te has perdido el punto de la pregunta. Se preguntaba si había algún soporte integrado para hacer cumplir con precisión que la columna no debería ser actualizable.
Martin Smith

@MartinSmith Exactamente - también tenemos una columna modificada y solo tenía curiosidad por saber si existe un soporte integrado para solo lectura
Philipp M
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.