我在SQL Server 2005中创建了一个检查约束,但是此检查约束不起作用。 SQL Server Management Studio通过insert语句告诉我以下消息:
Msg 547,Level 16,State 0,Line 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,则insert语句可以成功完成,如果返回值大于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
感谢您的帮助。
答案 0 :(得分:2)
我能够100%重现您的问题。试试这个新的
以下示例。现在我的table table1是空的,我无法插入
任何数字进入它:)非常有趣的情况,绝对是
和你的一样,我相信。
“也许当您的UDF代码被执行时,它已经看到了同样的情况
你想要插入的行(它看到它在表中)。
我不知道内部工作,现在没有太多时间来检查它。
但这可能是问题所在。我的UDF不会根据某些执行检查
选择在同一张表中,这是在概念上不同的
你的例子和我的例子。“
好的,经过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
答案 1 :(得分: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