我有2列(A as bool
和B as text
)的表,这些列可以是:SQL服务器:存储过程或函数
- 两者空
- 如果A是假的,则B应为空
- 如果A为真,则B应该是不为空
有规则。我想要创建一个存储过程或函数来在添加或更新行时(通过触发器)检查这些规则。什么更好,存储过程或函数?如果功能,哪种类型?一般来说,哪个变体是最好的(返回布尔值或其他方式等)?
我有2列(A as bool
和B as text
)的表,这些列可以是:SQL服务器:存储过程或函数
有规则。我想要创建一个存储过程或函数来在添加或更新行时(通过触发器)检查这些规则。什么更好,存储过程或函数?如果功能,哪种类型?一般来说,哪个变体是最好的(返回布尔值或其他方式等)?
我想你是在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)
) ;
我也赞成。对于这种情况,这可能是最好的答案。如果逻辑对于像这样的“在线”解决方案变得太复杂,我的答案是“可能性”。 – granadaCoder 2013-02-21 20:37:38
我会用一个检查约束有线到一个UDF。
下面是一个愚蠢的例子验证,如果你插入一个人,他们的年龄将大于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
检查约束可能是这样做的方法,因为UDF对于在大型数据集上检查像这样的东西不会非常高效 – JNK 2013-02-21 16:30:08
我同意CHECK是最有可能的候选者。请记住,我的示例是一个检查限制,但也使用UDF。但是,如果需要,UDF允许进行一些“高级”检查,所以我提供了这个选项。如果他能以正常的方式获得胜利,那将是一条可行的路。 – granadaCoder 2013-02-21 16:33:32
看过这个问题稍微好一点我的例子有点没有意义:)并且这更好地捕获它... – chrisb 2013-02-21 16:41:41
为什么不使用触发器? – Kermit 2013-02-21 16:21:28
这里如何写触发器? – 2013-02-21 16:24:16
[阅读手册](http://msdn.microsoft.com/en-us/library/ms189799.aspx)。 – Kermit 2013-02-21 16:25:36