有没有办法阻止在表中的指定列中插入数据并仅使用默认(约束)值?
E.g。我有专栏:
LogInsert (DF GETDATE())
LogUser (DF ORIGINAL_LOGIN())
都使用DEFAULT
约束定义。我不想允许用户插入这些列,但在插入新行时使用默认值。
这会引起错误。
INSERT INTO T1
( C1
,C2
,LogInsert
,LogUser
)
VALUES ( 'A'
,'B'
,'20160101 10:53'
,'domain\user'
);
用户应该能够毫无错误地执行以下脚本。
INSERT INTO T1
( C1, C2 )
VALUES ( 'A', 'B' );
答案 0 :(得分:2)
您始终可以为用户提供工作视图而不是表格。然后,您可以选择完全隐藏列,或者(如此处)使它们计算,以便它们不能通过视图将值插入到列中:
create table dbo._T1 (
ID int IDENTITY(1,1) not null,
Inserted datetime2 constraint DF__T1_Inserted DEFAULT (SYSDATETIME()) not null,
ABC varchar(10) not null,
constraint PK__T1 PRIMARY KEY (ID)
)
go
create view dbo.T1
with schemabinding
as
select
ID,
COALESCE(Inserted,SYSDATETIME()) as Inserted,
ABC
from dbo._T1
go
insert into dbo.T1 (ABC) values ('abc')
go
insert into dbo.T1 (ABC,Inserted) values ('def',SYSDATETIME())
结果:
(1 row(s) affected)
Msg 4406, Level 16, State 1, Line 19
Update or insert of view or function 'dbo.T1' failed because it contains a derived or constant field.
所有用户查询都继续使用T1
。它恰好是一个观点,而不是一张桌子。
在上面,视图使用COALESCE(Inserted,SYSDATETIME())
。这里使用的内容并不重要,并且它不需要匹配,例如默认定义。所有重要的是某些计算在Inserted
列上执行,以便它成为视图中的只读列。
答案 1 :(得分:0)
您可以在表格上创建一个Check Constraint,例如下面的
CREATE TABLE [dbo].[T1]
(
[C1] VARCHAR(50)
,[LogInsert] DATETIME DEFAULT GETDATE()
,[LogUser] VARCHAR(500) DEFAULT ORIGINAL_LOGIN()
)
ALTER TABLE [T1] WITH CHECK ADD CONSTRAINT [CK_T1_LogInsert] CHECK ([LogInsert] = GETDATE())
ALTER TABLE [T1] WITH CHECK ADD CONSTRAINT [CK_T1_LogUser] CHECK ([LogUser] = ORIGINAL_LOGIN())
INSERT INTO [dbo].[T1] ([C1]) VALUES ('A')
INSERT INTO [dbo].[T1] ([C1]) VALUES ('B')
INSERT INTO [dbo].[T1] ([C1]) VALUES ('C')
SELECT * FROM [dbo].[T1]
--Will Fail
INSERT INTO [dbo].[T1] ([C1],[LogInsert]) VALUES ('D','2016-11-11 00:00')
INSERT INTO [dbo].[T1] ([C1],[LogUser]) VALUES ('D','Not Your UserName')
OR
您可以强制用户仅使用存储过程进行插入,而不允许将其作为参数进行插入,对于批量插入,也可以使用表变量。