使用 Microsoft SQL Management Studio,使约束依赖于用户生成的函数

Using Microsoft SQL Management Studio, make a constraint depend on a user-generated function

所以我 运行 遇到了一些关于让它工作的问题。 这是函数:

CREATE FUNCTION RSO_Affiliation_AdminID_is_Admin_Enforcer

@Admin_ID nvarchar(50)


RETURNS INT
AS
BEGIN

DECLARE @ACCESS nvarchar(50)
SET @ACCESS = (SELECT ACCESS FROM Student WHERE USER_ID = @ADMIN_ID)

IF (@ACCESS LIKE 'Admin')
        RETURN 1;

IF (@ACCESS LIKE 'SuperAdmin')
        RETURN 1;

RETURN 0; 
END
GO

我是 SQL 和 SQL 服务器管理工​​作室的新手,所以如果这里的语法有任何普遍错误,那将是主要问题,但就我而言已经看到了,这应该有效。本质上,这应该由 RSO_Affiliation table 的约束调用,新的 ADMIN_ID 作为参数,它应该对照 Student table 和 return 1 如果匹配 USER_ID 的访问级别是某种管理员,return 0 否则。

问题 1 是我在对象资源管理器中似乎找不到这个函数。尽管一遍又一遍地保存它,多次刷新并重新连接到数据库,但它不存在于所有函数文件夹中。它保存在我的文档中的 SQL Management Studio 文件夹中,但据我所知,我的实际数据库并不知道它的存在。顺便说一句,我将它创建为标量值函数。

问题 2 是我不知道应该在 RSO_Affiliation -> Check Constraints -> Expression 对话框 window 中输入什么的语法。从我从其他问题中看到的,

dbo.RSO_Affiliation_AdminID_is_Admin_Enforcer(ADMIN_ID) = 1

应该工作,但它不工作,可能是因为我不认为我的数据库知道在哪里寻找函数本身。

有什么见解吗?

编辑 所以我终于弄清楚要让 SMSS 将函数添加到数据库中,您需要使用工具栏左上角的“执行”按钮对其进行测试。我能够使用上面的代码在约束菜单中使用它没问题,除了一个:

它显然没有做任何事情。据推测,它是由具有待定 ADMIN_ID 的约束调用的,但我可以使用具有非管理员访问级别的学生来创建新的 RSO。知道为什么会这样吗?

假设 user_idstudent 中是唯一的,你可以用外键约束做你想做的事。这省去了用户定义函数的麻烦,但实现有几个陷阱。

首先,您需要一个学生的唯一密钥来识别谁是管理员或超级管理员:

alter table student add IsAdmin as (case when ACCESS in ('Admin', 'SuperAdmin') then 1 else 0 end);
create unique index unq_Student_IsAdmin on Student(user_id, IsAdmin);

然后,在你关心的table中创建一个外键约束:

alter table t add IsAdmin (1);
alter table t add constraint fk_t_student_isadmin
    foreign key (admin_id, IsAdmin) references student(user_id, IsAdmin);

这将保证您正在设置的 table 中的 admin_id 是管理员。