Чи можливо зробити один стовпець заново?


25

Мені цікаво, чи можна створити таблицю з стовпцем, який ніколи не можна змінити, але інші стовпці таблиці можуть.

Наприклад, я міг уявити CreatedByUserстовпчик, який ніколи не слід міняти.

Чи є для цього вбудована функціональність у SQL Server, чи це можливо лише через тригери чи щось інше?


Я не вірю, що існує інший спосіб, крім того, як реалізувати тригери і лише дозволяти створювати / оновлювати / видаляти заяви через процедури.
Марк С. Расмуссен


@MartinSmith дякую, за посилання. Я думаю, це була б відповідь на моє запитання. Тож зробіть це відповіддю, і я прийму його.
Philipp M

Відповіді:


19

Не існує вбудованої декларативної підтримки стовпців, що не оновлюються (за винятком конкретних попередньо визначених випадків, таких як IDENTITY)

Цей елемент Connect просив його, але його було відхилено. Додайте DRI, щоб застосувати незмінні значення стовпців

UPDATEТригер, ймовірно , буде найнадійнішим способом досягнення цієї мети. Він може перевірити IF UPDATE(CreatedByUser)помилку і повернути транзакцію, якщо це правда.


Посилання 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     

(Примітка. У таблиці є стовпець первинного ключа, який називається ідентифікатором).

Я відкидаю оновлення лише у тому випадку, якщо значення AssetTypeID зміниться. Таким чином, стовпець може бути присутнім в оновленні, і якщо значення не змінилося, воно пройшло б. (Мені знадобився цей шлях)


1
Якщо для певного запису значення AssetTypeIDвстановлено ненульове значення, і ви запускаєте, 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

1
@Philipp M Але ви можете скасувати доступ до таблиці та надати її перегляду. Не це?
msi77

-3

Чому ви оновлюєте створений стовпець?

Я мав би два стовпці - [created_by] та [модифікований_by] стовпчик, де перша вставка вставила б усі відповідні стовпці у запис, а будь-які наступні оновлення просто оновлять стовпчик [modified_by] (через тригер у додатку шару, ви можете структурувати своє оновлення, щоб змінити лише [модифікований_by] разом із відповідними стовпцями)


3
Я думаю, ви пропустили суть питання. Це було питання, чи існує якась вбудована підтримка, щоб точно виконати, щоб стовпець не оновлювався.
Мартін Сміт

@MartinSmith Рівно - у нас також є модифікований стовпчик, і мені було цікаво лише, чи існує вбудована підтримка для читання тільки
Philipp M
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.