절대 변경할 수없는 열이있는 테이블을 만들 수 있는지 궁금하지만 테이블의 다른 열은 가능합니다.
예를 들어 CreatedByUser
변경해서는 안되는 열을 상상할 수 있습니다.
이를 위해 SQL Server에 기본 제공 기능이 있습니까? 아니면 트리거 또는 다른 방법을 통해서만 가능합니까?
절대 변경할 수없는 열이있는 테이블을 만들 수 있는지 궁금하지만 테이블의 다른 열은 가능합니다.
예를 들어 CreatedByUser
변경해서는 안되는 열을 상상할 수 있습니다.
이를 위해 SQL Server에 기본 제공 기능이 있습니까? 아니면 트리거 또는 다른 방법을 통해서만 가능합니까?
답변:
업데이트 할 수없는 열에 대한 선언적 지원은 기본적으로 제공되지 않습니다 (예 :와 같은 사전 정의 된 특정 경우 제외 IDENTITY
)
이 Connect 항목이 요청했지만 거부되었습니다. 불변 열 값을 적용하기 위해 DRI 추가
UPDATE
트리거는 아마이 달성의 가장 강력한 방법이 될 것입니다. IF UPDATE(CreatedByUser)
오류를 확인 및 발생시키고 true 인 경우 트랜잭션을 롤백 할 수 있습니다.
나는 내 구현했습니다 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
(참고 : 테이블에는 ID라고하는 기본 키 열이 있습니다).
AssetTypeID 값이 변경되는 경우에만 업데이트를 거부합니다. 따라서 열이 업데이트에 존재할 수 있으며 값이 변경되지 않으면 통과하는 것보다 큽니다. (이 방법이 필요했습니다)
AssetTypeID
널이 아닌 값으로 설정되고 트리거에서 거짓으로 평가되어 해당 열을 편집 가능한 상태로두기 UPDATE Asset SET AssetTypeID = NULL WHERE Asset = the_id
때문에 롤백이 발생하지 않습니다 WHERE i.AssetTypeID <> d.AssetTypeID
.
파생 열이있는 뷰를 사용할 수 있습니다. 이 시도
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;
createdby 열을 업데이트하는 이유는 무엇입니까?
두 개의 열 [created_by] 및 [modified_by] 열이 있는데, 첫 번째 삽입은 레코드에 모든 해당 열을 모두 삽입하고 후속 업데이트는 [modified_by] 열을 업데이트합니다 (응용 프로그램의 트리거를 통해). 레이어는 각 열과 함께 [modified_by] 만 변경하도록 업데이트를 구성 할 수 있습니다.