我有一个包含2列(A as bool
和B as text
)的表格,这些列可以是:
有规则。我想创建一个存储过程或函数来在行添加或更新(通过触发器)时检查这些规则。什么是更好的,存储过程或功能?如果功能,哪种类型?一般来说,哪种变体是最好的(返回布尔或其他方式等)?
答案 0 :(得分:11)
我认为你是在CHECK
Constraint之后。
示例:
ALTER TABLE Xxx
ADD CONSTRAINT chk_Xxx
CHECK ( (A IS NULL AND B IS NULL)
OR (A = 0 AND B IS NULL)
OR (A = 1 AND B IS NOT NULL)
) ;
答案 1 :(得分:2)
我会使用连接到UDF的CHECK CONSTRAINT 这是一个愚蠢的例子,证明如果你插入一个人,他们的年龄将大于17岁。
if NOT exists (select * from sysobjects
where id = object_id('dbo.udfOlderThan17Check') and sysstat & 0xf = 0)
BEGIN
print 'Creating the stubbed version of dbo.udfOlderThan17Check'
EXEC ( 'CREATE FUNCTION dbo.udfOlderThan17Check ( @j as smallint ) RETURNS bit AS BEGIN RETURN 0 END')
END
GO
ALTER FUNCTION dbo.udfOlderThan17Check ( @Age smallint )
RETURNS bit AS
BEGIN
declare @exists int
select @exists = 0
if ( @Age IS NULL )
BEGIN
select @exists = 1 -- NULL VALUES SHOULD NOT BLOW UP THE CONSTRAINT CHECK
END
if ( @exists = 0 )
BEGIN
if @Age > 17
begin
select @exists = 1
end
END
return @exists
END
GO
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[Person]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
BEGIN
DROP TABLE [dbo].[Person]
END
GO
CREATE TABLE [dbo].[Person]
(
PersonUUID [UNIQUEIDENTIFIER] NOT NULL DEFAULT NEWSEQUENTIALID()
, Age smallint not null
)
GO
ALTER TABLE dbo.Person ADD CONSTRAINT PK_Person
PRIMARY KEY NONCLUSTERED (PersonUUID)
GO
ALTER TABLE dbo.Person
ADD CONSTRAINT [CK_Person_AgeValue] CHECK ([dbo].[udfOlderThan17Check]( [Age] ) != 0)
GO
以下是一些"测试":
INSERT INTO dbo.Person (Age) values (33)
INSERT INTO dbo.Person (Age) values (16)
INSERT INTO dbo.Person (Age) select 333 UNION select 58
INSERT INTO dbo.Person (Age) select 444 UNION select 4
select * from dbo.Person