You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL Server 2022行级安全自引用错误问题求助

修复方案

问题根因

SQL Server 2022的查询优化器对RLS predicate的循环依赖检测更严格:当访问User或UserRight表时,RLS会触发RLS.UserSameOrEditor函数,该函数调用HasEffectiveUserRole,后者又调用EffectiveUserRights访问UserRight表;同时CurrentUserId直接访问User表——而这两张表本身受RLS策略约束,形成间接循环引用,导致优化器在某些执行计划下抛出错误。

具体修复步骤

方案一:内联权限逻辑,消除函数链循环

直接修改RLS.UserSameOrEditor函数,跳过中间函数层,避免递归触发RLS:

ALTER FUNCTION [RLS].[UserSameOrEditor](@User int, @Subsystem int)
RETURNS TABLE 
WITH SCHEMABINDING
AS
RETURN 
(
    SELECT 1 AS 'Allow'
    WHERE 
        -- 当前登录用户直接匹配,允许访问
        @User = (SELECT Id FROM dbo.[User] WHERE UserName = ORIGINAL_LOGIN())
        -- 检查当前用户是否拥有指定子系统的编辑器权限(Role=8)
        OR EXISTS (
            SELECT 1
            FROM dbo.UserRight ur
            WHERE ur.[User] = (SELECT Id FROM dbo.[User] WHERE UserName = ORIGINAL_LOGIN())
              AND ur.Subsystem = @Subsystem
              AND (ur.Rights & 8) = 8
        )
)

方案二:拆分函数,解除SCHEMABINDING依赖

如果需要保留函数复用性,可将依赖表的函数改为无SCHEMABINDING(避免强制触发RLS约束检查):

  1. 重构CurrentUserId函数:
DROP FUNCTION IF EXISTS [dbo].[CurrentUserId]
GO
CREATE FUNCTION [dbo].[CurrentUserId]()
RETURNS int
AS
BEGIN
    DECLARE @Id int
    SELECT @Id = Id 
    FROM dbo.[User] 
    WHERE UserName = ORIGINAL_LOGIN()
    RETURN @Id
END
  1. 修改HasEffectiveUserRole函数,直接访问表而非调用EffectiveUserRights:
ALTER FUNCTION [dbo].[HasEffectiveUserRole](@Subsystem int, @Role int)
RETURNS bit
WITH SCHEMABINDING
AS
BEGIN
    DECLARE @Result bit, @UserId int
    SET @UserId = dbo.CurrentUserId()
    
    SELECT @Result = CASE WHEN (Rights & @Role) = @Role THEN 1 ELSE 0 END
    FROM dbo.UserRight ur
    WHERE ur.[User] = @UserId AND ur.Subsystem = @Subsystem
    
    RETURN COALESCE(@Result, 0)
END
  1. 保留原RLS.UserSameOrEditor函数即可。

临时应急方案(不推荐)

若上述重构暂时无法实施,可修改安全策略关闭SCHEMABINDING,但这会降低安全性(后续表结构变更可能破坏RLS逻辑):

ALTER SECURITY POLICY [RLS].[UserSecurity] 
WITH (SCHEMABINDING = OFF)
GO

验证修复效果

修改完成后,重启SQL Server服务(清除执行计划缓存),进行长时间测试:

  • 用普通用户登录,确认只能看到自身的用户信息和权限
  • 用拥有编辑器权限(Role=8)的用户登录,确认能正常访问所有用户数据

内容的提问来源于stack exchange,提问作者Node

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 04:43:09