È possibile creare una colonna in sola lettura?


25

Sono curioso di sapere se è possibile creare una tabella con una colonna che non può mai essere modificata, ma le altre colonne della tabella possono farlo.

Ad esempio, potrei immaginare una CreatedByUsercolonna che non dovrebbe mai essere cambiata.

Esiste una funzionalità integrata in SQL Server per questo o è possibile solo tramite trigger o qualcos'altro?


Non credo che ci sia un modo per aggirare questo se non l'implementazione di trigger e la possibilità di creare / aggiornare / cancellare istruzioni solo attraverso le procedure.
Mark S. Rasmussen,


@MartinSmith grazie, per il link. Immagino che sarebbe la risposta alla mia domanda. Quindi fagli una risposta e la accetterò.
Philipp M

Risposte:


19

Non esiste un supporto dichiarativo incorporato per le colonne non aggiornabili (ad eccezione di casi predefiniti specifici come IDENTITY)

Questo elemento Connect lo ha richiesto ma è stato rifiutato. Aggiungi DRI per applicare valori di colonna immutabili

Un UPDATEtrigger sarebbe probabilmente il modo più robusto per raggiungere questo obiettivo. Potrebbe verificare IF UPDATE(CreatedByUser)e generare un errore e ripristinare la transazione se vera.


Collegamento Archive.org al vecchio elemento della richiesta Connect collegato sopra: web.archive.org/web/20130402211121/http://connect.microsoft.com/…
Anssssss

7

Ho implementato l' UPDATE TRIGGERapproccio suggerito dalla risposta di Martin Smith come segue:

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 tabella ha una colonna Chiave primaria, chiamata ID).

Respingo l'aggiornamento solo se il valore di AssetTypeID cambia. Quindi la colonna potrebbe essere presente in un aggiornamento e, se il valore non fosse cambiato, sarebbe passato. (Avevo bisogno in questo modo)


1
Se per un determinato record AssetTypeIDè impostato su un valore non nullo e si esegue UPDATE Asset SET AssetTypeID = NULL WHERE Asset = the_idche non si verificherebbe alcun rollback perché WHERE i.AssetTypeID <> d.AssetTypeIDnel trigger si valuterebbe false, lasciando modificabile quella colonna.
Christiaan Westerbeek,

3

È possibile utilizzare una vista con colonna derivata. Prova questo

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;

Non sono sicuro di cosa intendi. Puoi elaborare?
Philipp M

Ma puoi semplicemente aggiornare la tabella e modificarne i valori
Philipp M

1
@Philipp M Ma puoi revocare l'accesso al tavolo e concederlo alla vista. Non è così?
msi77,

-3

Perché stai aggiornando la colonna creata da?

Avrei due colonne una [creata_by] e una [modificata_by], in cui il primo inserto inseriva tutte le rispettive colonne nel record e qualsiasi aggiornamento successivo avrebbe semplicemente aggiornato la colonna [modificata_by] (tramite un trigger attivato nell'applicazione livello puoi strutturare il tuo aggiornamento per cambiare solo il [modificato_by], insieme alle rispettive colonne)


3
Penso che tu abbia perso il punto della domanda. Stava chiedendo se esistesse un supporto integrato per imporre con precisione che la colonna non dovesse essere aggiornabile.
Martin Smith

@MartinSmith Esatto - abbiamo anche una colonna modificata e ero solo curioso di sapere se esiste un supporto incorporato per readonly
Philipp M
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.