0

我在SQL Server 2005中創建了一個檢查約束,但是這個檢查約束不起作用。在SQL Server Management Studio中的一個INSERT語句告訴我下面的消息:爲什麼這個Check約束不起作用?

消息547,級別16,狀態0,第1行
INSERT語句衝突與CHECK約束 「MY_CHECK_CONSTAINT」。數據庫「MY_DB」中出現衝突,表「dbo.MY_TABLE」,列「MY_COLUMN」。

我已經加入了檢查約束用下面的代碼:

ALTER TABLE MY_TABLE WITH NOCHECK 
ADD CONSTRAINT CK_MY_CHECK_CONSTRAINT CHECK (dbo.MY_FUNCTION(MY_PARAMETER)<1) 

調用函數 「創建my_function」 返回一個int。

我的目標是,如果我的函數返回一個int小於1的插入語句可以成功完成,如果返回值大於0的INSERT語句,將被終止。現在

我的問題是,我的函數返回值0,但INSERT語句,始終終止。我究竟做錯了什麼?

我的函數的代碼如下:

CREATE FUNCTION MY_FUNCTION(@MY_PARAMETER uniqueidentifier) 
RETURNS int 
AS 
BEGIN 
    declare @return int = 0 
    SET @return = (SELECT COUNT(MY_COLUMN) FROM MY_TABLE WHERE MY_COLUMN= @MY_PARAMETER) 
return @return 
END 

感謝您的幫助。

+1

什麼是錯的是你的*假設*該函數返回0,不正確。但是我們不能告訴你爲什麼這是不正確的,因爲你沒有向我們展示它的代碼。 –

+0

我有上帝現在添加了我的函數的代碼。我希望這可以幫助你。 –

+0

只需在'MY_COLUMN'上添加一個唯一約束。不要試圖在標量UDF中使用檢查約束。 –

回答

1

我能夠以100%的比例再現您的問題。下面試試這個新的
例子。現在我的表table1是空的,我不能插入
任何數字到它:)非常有趣的情況下,絕對是你的相同的
,我相信。

「也許是執行你的UDF代碼時,它已經看到這個同一
行,你只是試圖插入(它認爲它在表)。
我不知道的內部運作現在沒有太多的時間來檢查它
但這可能是問題。我的UDF不執行在同一臺基於一些
選中一個,那就是我們的
你的榜樣和我的例子之間的不同概念。」

OK,5分多鐘的研究後,結果發現我的猜測是正確的。
當你的UDF被調用時,它認爲你只是想
插入行。

看到這裏接受的答案。

Check constraint UDF with multiple input parameters not working

所以 - 神祕發現,似乎:)


--- 1 --- 

USE [test] 
GO 

/****** Object: UserDefinedFunction [dbo].[ContainsNumber] Script Date: 11/26/2013 07:06:41 ******/ 
SET ANSI_NULLS ON 
GO 

SET QUOTED_IDENTIFIER ON 
GO 

CREATE FUNCTION [dbo].[ContainsNumber] 
(
     @number int 
) 
RETURNS INT AS 

BEGIN 

declare @result int 

select @result = count(*) 
from test.dbo.table1 
where 
number = @number 

if (@result > 0) 
begin 
    set @result = 1 
end 

return @result 

END 


GO 



--- 2 --- 

USE [test] 
GO 

/****** Object: Table [dbo].[table1] Script Date: 11/26/2013 07:06:33 ******/ 
SET ANSI_NULLS ON 
GO 

SET QUOTED_IDENTIFIER ON 
GO 

CREATE TABLE [dbo].[table1](
    [id] [int] IDENTITY(1,1) NOT NULL, 
    [number] [int] NULL, 
CONSTRAINT [PK_table1] PRIMARY KEY CLUSTERED 
(
    [id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 

ALTER TABLE [dbo].[table1] WITH CHECK ADD CONSTRAINT [CK_table1] CHECK (([dbo].[ContainsNumber]([number])=(0))) 
GO 

ALTER TABLE [dbo].[table1] CHECK CONSTRAINT [CK_table1] 
GO 
+0

非常感謝您的幫助:)現在一切正常。這是解決方案。 –

0

1)也許你可以在你的代碼試試這個:

SELECT @return = COUNT(MY_COLUMN) 
FROM MY_TABLE WHERE MY_COLUMN = @MY_PARAMETER 

,而不是你做了什麼。

2)嘗試命名變量不是@return,但例如@結果。

3)嘗試在正常呼叫之外行走您的功能。

4)另外,你可能想試試下面這個測試。 我沒有看到它的任何問題...但是,好吧, 它不是100%與你的相同。

下面的檢查約束正常工作,並使用 我的用戶定義函數 IsEvenNumber。

----- 1 ----- 

USE [test] 
GO 

SET ANSI_NULLS ON 
GO 

SET QUOTED_IDENTIFIER ON 
GO 



CREATE FUNCTION [dbo].[IsEvenNumber] 
(
     @number int 
) 
RETURNS INT AS 

BEGIN 

declare @result int 

set @result = 1 

if (((@number) % 2) <> 0) 
begin 
    set @result = 0 
end 


return @result 


END 



GO 




----- 2 ----- 


USE [test] 
GO 

SET ANSI_NULLS ON 
GO 

SET QUOTED_IDENTIFIER ON 
GO 

CREATE TABLE [dbo].[table1](
    [id] [int] IDENTITY(1,1) NOT NULL, 
    [number] [int] NULL, 
CONSTRAINT [PK_table1] PRIMARY KEY CLUSTERED 
(
    [id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 

ALTER TABLE [dbo].[table1] WITH CHECK ADD CONSTRAINT [CK_Table1] CHECK (([dbo].[IsEvenNumber]([number])<(1))) 
GO 

ALTER TABLE [dbo].[table1] CHECK CONSTRAINT [CK_Table1] 
GO 



----- 3 ----- 


insert into table1(number) values (3) -- OK 

insert into table1(number) values (10) -- FAILED 

insert into table1(number) values (0) -- FAILED 

insert into table1(number) values (5) -- OK 
+0

如果我做你的解決方案一切工作正常,但當我嘗試做我的功能和我的表一樣,所以我收到以下錯誤信息:消息547,級別16,狀態0,行1 ALTER TABLE語句與檢查約束「CK_MY_CONSTRAINT」。數據庫「MY_DB」中出現衝突,表「dbo.MY_TABLE」,列「MY_COLUMN」。 –

+0

我不知道爲什麼,但我不能改變我的表添加檢查約束而不放置NOCHECK。 –

+0

我試圖用一個固定值作爲參數調用我的函數,並且我確定我的函數可以按我的意願工作。 –