存储过程未返回预期结果:Survey权限展示需求实现求助
问题分析
你的核心需求是返回所有Survey列表,并标记当前用户是否对该Survey拥有IsViewer或IsAuthor权限(即checked状态),但当前的视图和存储过程逻辑存在两个关键问题:
视图
vRightsOnSurveys的UNION逻辑错误:
你通过UNION把所有Survey都添加了一条UserID=-1的默认权限记录(IsViewer和IsAuthor都为1),这会导致查询时同一Survey会出现两条记录:一条是默认的UserID=-1的记录,另一条是用户实际的权限记录(如果存在)。这种结构无法直接让你得到“该用户是否拥有该Survey权限”的单一判断结果。存储过程只是过滤记录,未做聚合判断:
当前存储过程只是从视图中过滤出符合SurveyID和UserID的记录,但返回的是多条零散的权限记录,无法直接映射到“每个Survey是否被当前用户授权”的需求,前端自然无法正确渲染勾选状态。
解决方案
我们不需要依赖那个有问题的视图,直接在存储过程中实现“全Survey列表+用户权限判断”的逻辑即可。核心思路是:
- 先获取所有Survey的基础信息
- 通过关联查询匹配当前用户的权限记录(
RightsOnSurveys表) - 用条件判断生成
checked字段,标记用户是否拥有对应权限
以下是修正后的存储过程:
ALTER PROCEDURE [dbo].[GetUserRightsOnSurveys] @SurveyID int = NULL, @UserID int = NULL AS BEGIN SET NOCOUNT ON; -- 优化性能,避免返回影响行数的冗余消息 SELECT s.ID AS SurveyID, s.Name, -- 生成checked字段,判断用户权限状态 CASE -- 未指定用户时,直接返回未勾选状态 WHEN @UserID IS NULL THEN CAST(0 AS bit) -- 存在匹配权限且IsViewer/IsAuthor为true时,返回已勾选 WHEN EXISTS ( SELECT 1 FROM RightsOnSurveys ros WHERE ros.SurveyID = s.ID AND ros.UserID = @UserID AND (ros.IsViewer = 1 OR ros.IsAuthor = 1) ) THEN CAST(1 AS bit) -- 其他情况返回未勾选 ELSE CAST(0 AS bit) END AS Checked FROM Surveys s -- 支持按SurveyID过滤(传入具体值时生效) WHERE (@SurveyID IS NULL OR s.ID = @SurveyID) ORDER BY s.Name; -- 可选:按名称排序,提升前端展示体验 END
逻辑说明
- 全Survey覆盖:直接从
Surveys表查询所有记录,确保不会遗漏任何Survey条目。 - 权限判断逻辑:
- 当
@UserID为NULL时,返回Checked=0(无指定用户时无法判定权限) - 当
@UserID存在时,通过EXISTS子查询快速验证该用户是否拥有当前Survey的查看或编辑权限
- 当
- 参数兼容:完整保留了
@SurveyID和@UserID为NULL的支持,符合你的原始需求。
测试示例
你可以通过以下语句验证存储过程的效果:
-- 查询所有Survey,判断ID为1的用户的权限情况 EXEC GetUserRightsOnSurveys @UserID = 1; -- 查询ID为5的Survey,判断ID为1的用户的权限情况 EXEC GetUserRightsOnSurveys @SurveyID = 5, @UserID = 1; -- 查询所有Survey,不指定用户(Checked全为0) EXEC GetUserRightsOnSurveys;
内容的提问来源于stack exchange,提问作者Unexpected_error
相关产品推荐
相关产品推荐

