Sql server 2008 Count Distinct在SQL Server 2008的UDF中不起作用

Sql server 2008 Count Distinct在SQL Server 2008的UDF中不起作用,sql-server-2008,tsql,user-defined-functions,Sql Server 2008,Tsql,User Defined Functions,我在创建查询中计数不同的自定义项时遇到问题。我创建了一个表amtest,该表包含以下内容: CREATE TABLE [dbo].[amtest]( [ztime] [datetime] NULL, [zutime] [datetime] NULL, [zid] [int] NOT NULL, [xamacadyr] [int] NOT NULL, [xamreg] [varchar](20) NOT NULL, [xmobile] [varcha

我在创建查询中计数不同的自定义项时遇到问题。我创建了一个表amtest,该表包含以下内容:

CREATE TABLE [dbo].[amtest](
    [ztime] [datetime] NULL,
    [zutime] [datetime] NULL,
    [zid] [int] NOT NULL,
    [xamacadyr] [int] NOT NULL,
    [xamreg] [varchar](20) NOT NULL,
    [xmobile] [varchar](15) NULL,
    [xamclasssec] [varchar](30) NULL,
PRIMARY KEY CLUSTERED 
(
    [zid] ASC,
    [xamacadyr] ASC,
    [xamreg] ASC
)
amtest表中的数据如下所示:

zid xamacadyr   xamreg      xmobile         xamclasssec
100000  2013        201508001   01713236075     Section-B
100000  2014        201508003   01713236072     Section-A
100000  2015        201508001   01713236071     Section-A
100000  2015        201508003   01713236073     Section-A
100000  2015        201508004   01713236074     Section-A
alter table amtest  
add constraint chkAmtest  
check(dbo.CheckTest(xamreg)<=1)  
现在,我已经创建了一个带有参数xamreg的用户定义函数,这样,对于任何xamreg值,xamclasssec字段中都不能有2个不同的值。例如,这里对于xamreg中的201508001值,不应该有两个不同的值Section-A和Section-B,它应该只允许Section-A或Section-B。为此,我创建了以下UDF:

ALTER FUNCTION [dbo].[CheckTest](@xamreg varchar(30))
RETURNS int
AS
BEGIN
    DECLARE @retvar int;
    select @retvar = COUNT(*) from (select xamclasssec from amtest where xamreg=@xamreg group by xamclasssec) as tbl ;
    RETURN @retvar
END
我为amtest表创建了一个约束,如下所示:

zid xamacadyr   xamreg      xmobile         xamclasssec
100000  2013        201508001   01713236075     Section-B
100000  2014        201508003   01713236072     Section-A
100000  2015        201508001   01713236071     Section-A
100000  2015        201508003   01713236073     Section-A
100000  2015        201508004   01713236074     Section-A
alter table amtest  
add constraint chkAmtest  
check(dbo.CheckTest(xamreg)<=1)  

我犯了一个错误,因为它不工作?

首先,您的功能可以简化为:

CREATE FUNCTION [dbo].[CheckTest](@xamreg varchar(30))
RETURNS INT
AS
BEGIN
    RETURN (SELECT COUNT(DISTINCT xamclasssec) FROM amtest WHERE xamreg = @xamreg);
END
GO
我使用SQL FIDLE运行您的查询,它似乎可以工作,但仅使用INSERT:

如果我尝试设置不同的值,您会得到:

INSERT语句与CHECK约束chkAmtest冲突。 冲突发生在数据库db_3_5ec42的表dbo.amtest中, “xamreg”列

但您的解决方案有一个缺点,当更新发生时,它将不起作用

改用后触发器:


首先,您的功能可以简化为:

CREATE FUNCTION [dbo].[CheckTest](@xamreg varchar(30))
RETURNS INT
AS
BEGIN
    RETURN (SELECT COUNT(DISTINCT xamclasssec) FROM amtest WHERE xamreg = @xamreg);
END
GO
我使用SQL FIDLE运行您的查询,它似乎可以工作,但仅使用INSERT:

如果我尝试设置不同的值,您会得到:

INSERT语句与CHECK约束chkAmtest冲突。 冲突发生在数据库db_3_5ec42的表dbo.amtest中, “xamreg”列

但您的解决方案有一个缺点,当更新发生时,它将不起作用

改用后触发器:


如果我错了,让我知道,但是,这个UDF将返回2。
这就是你想要的吗?

如果我错了,请告诉我,但是,此UDF将返回2。
这就是你想要的吗?

不,我不想要。这不能正常工作,这就是为什么表中的值超过1。此UDF应仅取1个不同的值,它应仅取第A节或第BB节,但如果执行此查询:从amtest中选择xamclasssec中选择计数*,其中xamreg=201508001由xamclasssec分组作为tbl;它将返回2;是的,由于检查不起作用,查询正在执行,我想抵制这种情况。我已经有了另一个解决办法。别担心不,我不想那样。这不能正常工作,这就是为什么表中的值超过1。此UDF应仅取1个不同的值,它应仅取第A节或第BB节,但如果执行此查询:从amtest中选择xamclasssec中选择计数*,其中xamreg=201508001由xamclasssec分组作为tbl;它将返回2;是的,由于检查不起作用,查询正在执行,我想抵制这种情况。我已经有了另一个解决办法。别担心,老板,这个自定义项可以很好地使用插入查询,但是当我更新任何记录时,它都不起作用,我没有检查你的替代解决方案。但是,在更新记录的过程中,UDF不可能进行检查吗?正如我所说,您的UDF将检查数据,但在更新完成之前。因此,不,用UDF是不可能的。在触发器正确后way@ChistiaChowdhury很好,把标记当作答案;是的,老板,这个自定义项可以很好地使用插入查询,但是当我更新任何记录时,它都不起作用,我没有检查你的替代解决方案。但是,在更新记录的过程中,UDF不可能进行检查吗?正如我所说,您的UDF将检查数据,但在更新完成之前。因此,不,用UDF是不可能的。在触发器正确后way@ChistiaChowdhury很好,把标记当作答案;