前几天有一个需求很头痛,部门是有上下级关系的,在给部门的经理赋予角色和权限的时候,通常我们都会认为假如经理A的部门是1,那么我给了他部门1 的管理权限,那么1的下级部门101,102,103 “自然而然的”都应该给他管理。

这个自然而然可不是想当然的那么自然,尤其系统没有设置批量添加功能的时候,靠人工一个个的去添加下级部门真的是不现实。更过分的是,用户要求整个公司的管理人员都要自动的拥有其所在部门的所有下级部门的某个权限,emmmm,烦死了,领导那么多,做事的小弟却只有一个,一个个手动添加到何时???

由于整个系统都是依赖sql存储过程,别问我为什么不写java啊net啊c#啊什么的,这个系统是公司购买的,全部都是存储过程,几千上万个吧,几千行的存储过程能把人看瞎咯!没办法只能随行就市写起来咯。

思路也很清楚,首先要把这些管理人员和所在部门找到,这是其一,其二是要把这些管理人员的下级部门找到,这两个都找到以后,要顺序循环管理人员,然后把他的部门和权限关联起来。说起来容易做起来难,尤其我的存储过程还没达到精通的程度,也是反复琢磨,终于给搞出来了。

以下就是具体代码,仅供参考:

首先准备部门和下级部门数据,这个就比较简单了,一个简单的递归查询,写成存储过程以便调用。

CREATE PROCEDURE [dbo].[rsp_selectTreeofsubDep]  --查询下级部门
-- Add the parameters for the stored procedure here
@depid int --父部门id
AS
BEGIN
with cte as (
select d.depID ,d.AdminID from Department d
where DepID = @depid
union all
select d.DepID ,d.AdminID from Department d
inner join cte o on o.DepID = d.AdminID
)
select DepID from cte
END GO

  然后就是主存储过程,用来循环批量插入数据的:

CREATE Procedure [dbo].[rsp_insertMultitiesofDep]      --代理部门批量插入      

AS
DECLARE @i int, @RoleID int,@Depid int ----循环角色ID DECLARE @UserDepidTemp TABLE --部门负责人代号和其所在部门
(
UserID varchar(10),
Depid int
)
DECLARE @subDepidTemp TABLE --部门负责人的下级部门
(
Depid int
)
DECLARE @UserDepidRoleTemp TABLE --部门负责人角色和其所在部门
(
RoleID int,
Depid int,
FlagID TINYINT
)
BEGIN
--整理部门负责人代号和所在部门 ,将部门负责人的用户名和部门编号放到临时表
insert into @UserDepidTemp
select UserID,Depid from employee
where UserID in (select distinct e.UserID from employee e
left join Department d on e.DepID = d.DepID
join employee p on e.NID = p.MANAGER ) --整理部门负责人的角色ID和部门,将角色表的部门经理的角色和用户表的部门经理的部门放到临时表,标志位全部置0
insert into @UserDepidRoleTemp(RoleID,Depid,FlagID)
select RoleID ,depid ,0 from USER_ROLE u left join @UserDepidTemp b on u.UserID = b.UserID
where depid is not null ---开始循环角色,用户取自上面的角色代号和部门代号的临时表
SET @i=1
WHILE( @i>=1)
BEGIN
SELECT @RoleID=''
SELECT TOP 1 @RoleID = RoleID FROM @UserDepidRoleTemp WHERE FlagID=0 --顺序读取表中的第一个角色用户,即当前角色用户
SET @i=@@ROWCOUNT --受影响行数为1 select @Depid=''
select top 1 @Depid = Depid from @UserDepidRoleTemp WHERE RoleID=@RoleID --获取当前用户角色所在部门作为父部门,以便下一行查询下级部门列表
insert into @subDepidTemp EXEC rsp_selectTreeofsubDep @Depid --获取下级部门结果集
insert into ROLE_DEPT (ROLEID,DepID) SELECT @Roleid,Depid from @subDepidTemp --将当前循环表中的用户角色和查询到的下级部门放入角色部门表
IF @i<=0 GOTO Return_Lab --当i小于0时跳出循环
IF @@error=0
delete from @subDepidTemp --千万记得要删除下级部门临时表,这个表放的是当前角色用户的下级部门
UPDATE @UserDepidRoleTemp SET FlagID=1 WHERE ID = @ID --将用户角色和所在部门的标志位置1,下次循环将跳过该数据
Return_Lab:
END
END GO

嗯,如上,就上面这个存储过程,现在来看也不复杂,可是我还是写了好久,好几个地方数据都拿错了,导致测试表的结果总不对。

当然现在这种批量事务一般都用其他服务端语言解决了,仍然用纯sql实现的方案比较少了,我也是赶鸭子上架硬着头皮写,总算写出来了也算完成了一件事。

换新工作后每天就是sql,各种眼花缭乱的sql整到没脾气,存储过程虽然也能写,但是更深层次的事务管理和锁啊同步啊互斥啥的都没理解,能用就行,还需慢慢修行吧!也不知道纯sql能找到工作否。

sql存储过程中循环批量插入的更多相关文章

  1. SQL存储过程+游标 循环批量()操作数据

    本人收集的,挺有用的 1. 利用游标循环更新.删除MemberAccount表中的数据 DECLARE My_Cursor CURSOR --定义游标 FOR (SELECT * FROM dbo.M ...

  2. mysql 循环批量插入

    背景 前几天在MySql上做分页时,看到有博文说使用 limit 0,10 方式分页会有丢数据问题,有人又说不会,于是想自己测试一下.测试时没有数据,便安装了一个MySql,建了张表,在建了个whil ...

  3. sql server 使用SqlBulkCopy批量插入数据库

    sql server sqlbulkcopy 批量数据插入数据库使用的是System.Data.SqlClient中的 SqlBulkCopy批量数据插入数据库 sql server 使用SqlBul ...

  4. 在SQL存储过程中给条件变量加上单引号

    在SQL存储过程中给条件变量加上单引号,不加语句就会出问题,以下就是在存储过程中将条件where设置成了动态变化的,给where赋完值再和前面的语句拼接,再execute(SQL) ), )), )+ ...

  5. sql存储过程中使用 output

    1.sql存储过程中使用 output CREATE PROCEDURE [dbo].[P_Max] @a int, -- 输入 @b int, -- 输入 @Returnc int output - ...

  6. sql存储过程中使用 output、nvarchar(max)

    1.sql存储过程中使用 output CREATE PROCEDURE [dbo].[P_Max] @a int, -- 输入 @b int, -- 输入 @Returnc int output - ...

  7. JDBC中的批量插入和乱码解决

    字符集-乱码问题 用JDBC访问MySql数据库的时候,如果JDBC使用的字符集和MySql使用的字符集不一致,那么会导致乱码发生.解决办法当时是在使用JDBC的时候指定和数据库一样的字符集.我们可以 ...

  8. mysql使用存储过程&函数实现批量插入

    写这边文章的目的,是想结合mysql 存储过程+函数完成一个批量删除的功能吧...正好也好加深下对procedure和function的熟练操作吧...废话不多说,我就直接上表结构啦哈,如下: cre ...

  9. 怎样SQL存储过程中执行动态SQL语句

    MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和sp_executesql;通常,sp_executesql则更具有优势,它提供了输入输出接口,而EXEC没有.还有一个最大的好处就 ...

随机推荐

  1. Java编程思想:文件加锁

    import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; i ...

  2. 【NOIP2017】图书管理员-C++

    描述 图书馆中每本书都有一个图书编码,可以用于快速检索图书,这个图书编码是一个 正整数. 每位借书的读者手中有一个需求码,这个需求码也是一个正整数.如果一本书的图 书编码恰好以读者的需求码结尾,那么这 ...

  3. duilib加消息

    一.加消息 1. public INotifyUI, 2. void Notify(TNotifyUI& msg); 3. Notify实现 4. m_pManager->AddNoti ...

  4. Excel催化剂开源第41波-网抓网络采集类库及工具分享

    在VBA开发网抓程序中,会用到xmlhttp/winHttp.winHttprequest.5.1等组件,当时笔者也是这样进入了网抓领域的,这些都是非常过时的东西,在.Net的开发中,有大量的更好用的 ...

  5. SpringBoot集成beetl模板快速入门

    SpringBoot集成beetl模板快速入门 首次探索 beetl官方网址:http://ibeetl.com/ 创建SpringBoot工程(idea) 新建工程 选择创建Spring工程 书写包 ...

  6. DataNode的工作机制

    DataNode的工作机制 一个数据块在DataNode以文件的形式在磁盘上保存,分为两个文件,一个是数据本身, 一个是元数据信息(包括数据的长度,校验和,时间戳) 1.DataNode启动后,向Na ...

  7. php--学习封装类 (一)(操作mysql数据库的数据访问)

    <?php class DBDA //定义一个类 { //定义成员变量,不能直接定义,前面要加上public或者是private public $host = "localhost&q ...

  8. SSM - Mybatis SQL映射文件

    MyBatis 真正的力量是在映射语句中.和对等功能的jdbc来比价,映射文件节省很多的代码量.MyBatis的构建就是聚焦于sql的. sql映射文件有如下几个顶级元素:(按顺序) cache配置给 ...

  9. Jsp机试题 (用户登录用户注册/用户注销功能)

    1. 用户登录 实现用户登录,功能,三个页面登录页面login.jsp,登录逻辑处理页面loginSubmit.jsp,欢迎页面welcome.jsp.用户再登录页面输入用户名和密码,前台页面使用js ...

  10. Integrating Thymeleaf with Spring

    这个是基于注解的配置方式,基于配置文件的http://www.cnblogs.com/honger/p/6875148.html 一.整体结构图 二.web.xml文件,这里使用了注解的方式 < ...