Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 使用检查约束确定是否基于另一列值将位列和设置为true(可能)?_Sql_Sql Server_Sql Server 2008 - Fatal编程技术网

Sql 使用检查约束确定是否基于另一列值将位列和设置为true(可能)?

Sql 使用检查约束确定是否基于另一列值将位列和设置为true(可能)?,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,去elaborate 是否可以强制执行一个规则,其中只有一个记录项可以将名为“IsPrimaryUser”的列设置为true,而由另一列分组的所有其他列都设置为false。确定哪个条目将具有真正的“IsPrimaryUser”字段的条件是CompanyId列 我只关心是否可以使用检查约束来完成。显然,有一种SQL方法可以处理类似的问题 例如: 用户表 int UserId | int CompanyId |位IsPrimaryUser 数据: Check约束仅适用于单行,但可以在约束内使用标量U

去elaborate

是否可以强制执行一个规则,其中只有一个记录项可以将名为“IsPrimaryUser”的列设置为true,而由另一列分组的所有其他列都设置为false。确定哪个条目将具有真正的“IsPrimaryUser”字段的条件是CompanyId列

我只关心是否可以使用检查约束来完成。显然,有一种SQL方法可以处理类似的问题

例如:

用户表

int UserId | int CompanyId |位IsPrimaryUser

数据:


Check约束仅适用于单行,但可以在约束内使用标量UDF

您可以使用检查表中其他行的UDF来违反单行检查。虽然与触发器不同,在触发器中可以单独访问已删除的虚拟表和进程,但SQL Server似乎将记录保存在某种事务中,并在更改后对每一行执行检查,最后批量接受或中止CRUD

请参阅此测试用例

创建表

create table usertable (UserId int,
CompanyId int, IsPrimaryUser int)
填充

insert usertable select
1, 1, 1 union all select
2, 1, 0 union all select
3, 1, 0 union all select
4, 1, 0 union all select
5, 2, 1 union all select
6, 2, 0 union all select
7, 2, 0 union all select
8, 2, 0
标量函数助手

create function dbo.anyprimaryuser(@userid int, @company int) returns bit as
begin
return
    case when exists (
    select * from usertable
    where companyid=@company and isprimaryuser=1 and userid<>@userid)
    then 1 else 0 end
end
测验


(注意)在Martin下面的评论之后,我更新了答案,检查约束仅对一行有效,但您可以在约束中使用标量UDF

您可以使用检查表中其他行的UDF来违反单行检查。虽然与触发器不同,在触发器中可以单独访问已删除的虚拟表和进程,但SQL Server似乎将记录保存在某种事务中,并在更改后对每一行执行检查,最后批量接受或中止CRUD

请参阅此测试用例

创建表

create table usertable (UserId int,
CompanyId int, IsPrimaryUser int)
填充

insert usertable select
1, 1, 1 union all select
2, 1, 0 union all select
3, 1, 0 union all select
4, 1, 0 union all select
5, 2, 1 union all select
6, 2, 0 union all select
7, 2, 0 union all select
8, 2, 0
标量函数助手

create function dbo.anyprimaryuser(@userid int, @company int) returns bit as
begin
return
    case when exists (
    select * from usertable
    where companyid=@company and isprimaryuser=1 and userid<>@userid)
    then 1 else 0 end
end
测验


(注意)我在下面Martin的评论后更新了答案

这似乎是一个非最佳安排。为什么不使用列CompanyID和列CompanyID作为主键的PrimaryUser表?为什么您只关心是否可以使用检查约束来完成?一个唯一的过滤索引可以很容易地完成这项工作。@Martin只是因为我对它们知之甚少,并且很好奇它们能有多灵活。Martin同意:一个唯一的过滤索引是处理这个问题的正确方法。@Matthew-我想它们可以被使用,但是有很多事情需要小心。RE:和。这看起来像是一个非最优安排。为什么不使用列CompanyID和列CompanyID作为主键的PrimaryUser表?为什么您只关心是否可以使用检查约束来完成?一个唯一的过滤索引可以很容易地完成这项工作。@Martin只是因为我对它们知之甚少,并且对它们的灵活性感到好奇。Martin同意:一个唯一的过滤索引是处理这个问题的正确方法。@Matthew-我想它们是可以使用的,但是有很多事情需要小心RE:and。你可以称为标量来自检查约束的UDF,但这是一个不必要的麻烦。您可以从检查约束调用标量UDF,但这是一个不必要的麻烦。