0

我在 SQL Server 2005 中创建了一个检查约束,但是这个检查约束不起作用。SQL Server Management Studio 通过插入语句告诉我以下消息:

消息 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。

我的目标是,如果我的函数返回一个小于 1 的 int,则插入语句可以成功完成,如果返回值大于 0,则必须终止插入语句。

我现在的问题是我的函数返回值 0 但插入语句总是终止。我究竟做错了什么?

我的函数代码如下:

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 

谢谢你的帮助。

4

2 回答 2

2

我能够 100% 重现您的问题。试试
下面这个新例子。现在我的表 table1 是空的,我不能在其中插入
任何数字 :) 非常有趣的情况
,我相信和你的情况完全一样。

“也许当你的 UDF 代码被执行时,它已经看到了
你试图插入的同一行(它看到它在表中)。
我不知道内部工作原理,现在没有太多时间检查但这
可能是问题所在。我的 UDF 不会根据同一张表中的某些 SELECT 执行检查,这就是 您的示例和我的示例
在概念上的不同之处。”

好的,经过 5 分钟的研究,结果证明我的猜测是正确的。
当您的 UDF 被调用时,它会看到您正试图
插入的行。

请参阅此处接受的答案。

使用多个输入参数检查约束 UDF 不起作用

所以 - 神秘被发现,似乎:)


--- 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
于 2013-11-26T12:08:46.910 回答
0

1)也许你可以在你的代码中试试这个:

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

而不是你所做的。

2) 尝试将变量命名为不是@return,而是例如@result。

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
于 2013-11-26T09:34:39.513 回答