it-swarm-eu.dev

Je možné vytvořit jeden sloupec jen pro čtení?

Jsem zvědavý, jestli je možné vytvořit tabulku se sloupcem, který nelze nikdy změnit, ale ostatní sloupce tabulky je možné.

Mohl bych si například představit sloupec CreatedByUser, který by se nikdy neměl měnit.

Existuje pro to integrovaná funkce v SQL Serveru nebo je to možné pouze pomocí spouštěčů nebo něčeho jiného?

28
Philipp M

Neexistuje vestavěná deklarativní podpora pro neaktualizovatelné sloupce (s výjimkou konkrétních předdefinovaných případů, jako je například IDENTITY)

Tato položka Connect to vyžadovala, ale byla odmítnuta. Přidejte DRI pro vynucení neměnných hodnot sloupců

Spouštěč UPDATE by pravděpodobně byl nejrobustnějším způsobem, jak toho dosáhnout. Mohl by zkontrolovat IF UPDATE(CreatedByUser) a vyvolat chybu a vrátit transakci, pokud je true.

22
Martin Smith

Udělal jsem implementaci UPDATE TRIGGER přístup navržený odpověď Martina Smitha takto:

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     

(Poznámka: Tabulka obsahuje sloupec Primární klíč nazvaný ID).

Aktualizaci odmítám pouze v případě, že se změní hodnota AssetTypeID. Sloupec by tedy mohl být přítomen v aktualizaci, a pokud by se hodnota nezměnila, než by procházel. (Potřeboval jsem to tímto způsobem)

8
jaraics

Můžete použít pohled s odvozeným sloupcem. Zkuste to

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;
3
msi77