当前位置: 首页 > 知识库问答 >
问题:

sql - 目录要加权限控制,SQL得怎么写?

程城
2024-07-29

项目有个目录,需要加权限,页面上只渲染当前用户拥有的"巡检方案"所在的目录节点(子节点及它以上的所有父节点)。这是我渲染的目录所有的节点。各位大佬,请问sql该怎么写呀?
注:目录结构是动态的,不是固定的,后面公司的人可能会再加子节点

集团
    潮州
        工厂1
            办公楼
                男洗手间巡检方案
                杂物间巡检方案
            食堂
        工厂2
            技术楼
            食堂
    昆山
        工厂1
            办公楼
            研发楼

现在要加上权限控制,假如我拥有 "潮州 -> 工厂1 -> 办公楼" 下的巡检方案, 那我进来目录只渲染这样就好

集团
    潮州
        工厂1
            办公楼
                男洗手间巡检方案
                杂物间巡检方案

目录表在数据库里结构是
id, parent_id, name

权限表的是
id directory_id(目录的主键) user_id

我程序查出来的数据明细大致是, 然后用递归的方法生成前端目录需要的结构,返回到前端渲染。
1 0 集团
2 1 潮州
3 1 昆山
4 2 工厂1
5 4 办公楼
...

前端我是用element-ui的el-tree,所以结构是这样的。数据库查出来的明细,也希望按这个上面的明细一样。

[
    'label': '集团',
    'id': 0,
    children:[
        ...
    ]
]

共有1个答案

上官自明
2024-07-29

从权限表中找到当前用户拥有权限的所有目录节点及其所有父节点,然后根据这些数据生成前端需要的树状结构。
directory 表结构:

CREATE TABLE directory (
    id INT PRIMARY KEY,
    parent_id INT,
    name VARCHAR(255)
);

permissions 表结构:

CREATE TABLE permissions (
    id INT PRIMARY KEY,
    directory_id INT,
    user_id INT
);

当前用户的 user_id 为 :user_id。首先,我们需要递归地找到当前用户拥有权限的所有目录节点及其所有父节点。

WITH RECURSIVE DirectoryTree AS (
    -- 获取当前用户有权限的目录节点
    SELECT d.id, d.parent_id, d.name
    FROM directory d
    JOIN permissions p ON d.id = p.directory_id
    WHERE p.user_id = :user_id
    UNION ALL
    -- 递归地获取父节点
    SELECT d.id, d.parent_id, d.name
    FROM directory d
    JOIN DirectoryTree dt ON d.id = dt.parent_id
)
SELECT DISTINCT id, parent_id, name
FROM DirectoryTree;

不需要再建一个表。WITH RECURSIVE 是一个CTE(Common Table Expression),用于临时生成一个结果集,这个结果集可以在后续的SELECT查询中使用。

下面是完整的SQL查询语句,适用于SQL Server,来获取当前用户拥有权限的所有目录节点及其所有父节点:

-- 定义用户ID
DECLARE @user_id INT = 123; -- 替换成实际的用户ID

-- 递归CTE,找到所有有权限的节点及其父节点
WITH DirectoryTree AS (
    -- 获取当前用户有权限的目录节点
    SELECT d.id, d.parent_id, d.name
    FROM directory d
    JOIN permissions p ON d.id = p.directory_id
    WHERE p.user_id = @user_id
    UNION ALL
    -- 递归地获取父节点
    SELECT d.id, d.parent_id, d.name
    FROM directory d
    JOIN DirectoryTree dt ON d.id = dt.parent_id
)
-- 获取去重后的结果
SELECT DISTINCT id, parent_id, name
FROM DirectoryTree;

DECLARE @user_id INT = 123;:定义当前用户的ID,你需要将 123 替换为实际的用户ID。
WITH DirectoryTree AS 定义了一个递归CTE,首先从permissions表中获取当前用户有权限的目录节点。
UNION ALL 用于递归地获取这些目录节点的所有父节点。
最终的 SELECT DISTINCT 去重,得到所有相关的目录节点。
这个查询将返回当前用户有权限的所有目录节点及其所有父节点,你可以根据这些数据生成前端需要的树状结构。

在前端使用 element-ui 的 el-tree 组件时,可以将这个查询结果转换成适合 el-tree 组件的格式。

 类似资料:
  • CONTROLLING FILE AND DIRECTORY PERMISSIONS 并非操作系统的每个用户都应具有相同级别的文件和目录访问权限。与任何专业操作系统一样,Linux 具有保护文件和目录访问的方法。系统允许系统管理员(root 用户或文件所有者)通过赋予用户读取,写入或执行文件的权限来保护其文件免受不必要的访问或篡改。对于每个文件和目录,我们可以为文件所有者、特定用户组以及所有其他用

  • 本文向大家介绍vue要做权限管理该怎么做?如果控制到按钮级别的权限怎么做?相关面试题,主要包含被问及vue要做权限管理该怎么做?如果控制到按钮级别的权限怎么做?时的应答技巧和注意事项,需要的朋友参考一下 可以通过指令去做 Vue.directive('hasPermission', { bind(el, binding, vnode) { const permissions = vnode.con

  • 本页内容包括: 模块和源文件 访问级别 访问级别的使用原则 默认访问级别 单目标应用程序的访问级别 Framework的访问级别 访问控制语法 自定义类型 元组类型 函数类型 枚举类型 原始值和关联值 嵌套类型 子类 常量、变量、属性、下标 Getter和Setter 初始化 默认初始化方法 结构体的默认成员初始化方法 协议 协议继承 协议一致性 扩展 协议的扩展 泛型 类型别名 访问控制可以限定

  • 数据只能由所属的智能合约读写,智能合约默认无法读写其他智能合约的数据。 为了方便用户操作,使用智能合约的私有对象作为数据对象,系统通过反射,获取私有对象所属的智能合约和对象名。其他智能合约无法创建和获取该智能合约的私有对象,就无法读写对应的数据。 如果智能合约希望自己的数据能够被其他智能合约读写,需要智能合约主动提供数据操作接口,其他智能合约通过引用该合约,调用相应接口,从而操作相应数据。 智能合

  • 这是记录用户下载的表,想统计表内每个文章被下载了几次,也就是需要拿到一个文章ID,然后再求下这个ID出现的次数。

  • 本文向大家介绍asp.net core项目mvc权限控制:分配权限,包括了asp.net core项目mvc权限控制:分配权限的使用技巧和注意事项,需要的朋友参考一下 前面的文章介绍了如何进行权限控制,即访问控制器或者方法的时候,要求当前用户必须具备特定的权限,但是如何在程序中进行权限的分配呢?下面就介绍下如何利用Microsoft.AspNetCore.Identity.EntityFramew

  • 问题内容: 我们已将日志传送实现为数据库灾难恢复解决方案,并想知道是否可以使用T-SQL编写辅助服务器上主数据库的所有登录名,用户,角色权限等脚本,以便T- 可以将SQL安排为以SQL作业的形式运行吗? 我的目的是在发生D / R情况时,我们可以简单地将每个数据库的事务日志恢复到辅助服务器,而不必担心孤立的用户等。 谢谢您的帮助! 问题答案: 这里有一个登录复制脚本,旨在将登录复制到另一台服务器以

  • 问题内容: 我试图限制以下SQL语句。 我想做的是限制“父”行的数量。IE。如果我执行LIMIT 1,我将只收到一个费用项目,但仍获得与其相关的所有交易。 这将如何实现? 在此阶段,如果我执行LIMIT 1,我将获得一笔费用,并且只有一笔交易。 问题答案: 因此,假设我们可以排除用户表,则可以将其重写为: 现在,如果您想应用一个限制,您可以这样做: 那会做你想要的吗?显然,您需要对您的Expens