我有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