sql存储过程中循环批量插入
前几天有一个需求很头痛,部门是有上下级关系的,在给部门的经理赋予角色和权限的时候,通常我们都会认为假如经理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存储过程中循环批量插入的更多相关文章
- SQL存储过程+游标 循环批量()操作数据
本人收集的,挺有用的 1. 利用游标循环更新.删除MemberAccount表中的数据 DECLARE My_Cursor CURSOR --定义游标 FOR (SELECT * FROM dbo.M ...
- mysql 循环批量插入
背景 前几天在MySql上做分页时,看到有博文说使用 limit 0,10 方式分页会有丢数据问题,有人又说不会,于是想自己测试一下.测试时没有数据,便安装了一个MySql,建了张表,在建了个whil ...
- sql server 使用SqlBulkCopy批量插入数据库
sql server sqlbulkcopy 批量数据插入数据库使用的是System.Data.SqlClient中的 SqlBulkCopy批量数据插入数据库 sql server 使用SqlBul ...
- 在SQL存储过程中给条件变量加上单引号
在SQL存储过程中给条件变量加上单引号,不加语句就会出问题,以下就是在存储过程中将条件where设置成了动态变化的,给where赋完值再和前面的语句拼接,再execute(SQL) ), )), )+ ...
- sql存储过程中使用 output
1.sql存储过程中使用 output CREATE PROCEDURE [dbo].[P_Max] @a int, -- 输入 @b int, -- 输入 @Returnc int output - ...
- sql存储过程中使用 output、nvarchar(max)
1.sql存储过程中使用 output CREATE PROCEDURE [dbo].[P_Max] @a int, -- 输入 @b int, -- 输入 @Returnc int output - ...
- JDBC中的批量插入和乱码解决
字符集-乱码问题 用JDBC访问MySql数据库的时候,如果JDBC使用的字符集和MySql使用的字符集不一致,那么会导致乱码发生.解决办法当时是在使用JDBC的时候指定和数据库一样的字符集.我们可以 ...
- mysql使用存储过程&函数实现批量插入
写这边文章的目的,是想结合mysql 存储过程+函数完成一个批量删除的功能吧...正好也好加深下对procedure和function的熟练操作吧...废话不多说,我就直接上表结构啦哈,如下: cre ...
- 怎样SQL存储过程中执行动态SQL语句
MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和sp_executesql;通常,sp_executesql则更具有优势,它提供了输入输出接口,而EXEC没有.还有一个最大的好处就 ...
随机推荐
- UAVStack的慢SQL数据库监控功能及其实现
UAVStack是一个全维监控与应用运维平台.UAV.Monitor具备监控功能,包含基础监控.应用/服务性能监控.日志监控.业务监控等.在应用监控中,UAV可以根据应用实例画像:其中应用实例组件可以 ...
- 你必须知道的Docker镜像仓库的搭建
近期工作中发现用到的容器镜像越来越多(不多的时候没考虑过镜像仓库的问题),同一个容器镜像也存在多个版本,那么镜像仓库的搭建需求就涌现出来,本文就目前的几个常用镜像仓库的搭建进行介绍,我们可以根据需要选 ...
- 前后端分离之Swagger2
1. 问题描述 随着软件过程的不断发展,前后端分离开发模式被越来越的开发团队使用,今天介绍下前后分离中必用的接口设计与调试工具-swagger2,前端人员根据swagger的描述,进行参数的传递:前后 ...
- 【题解】旅行-C++
Description 某趟列车的最大载客容量为V人,沿途共有n个停靠站,其中始发站为第1站,终点站为第n站.在第1站至第n-1站之 间,共有m个团队申请购票搭乘,若规定:(1)对于某个团队的购票申请 ...
- VUE动态(自动)Loading【绑定到URL】,同页面多个Loading互不冲突
需求来源:当使用React时,使用 umi loading 很方便,页面对http请求发生改变时,也会自动改变loading的相关状态(true/false) 对VUE插件进行找寻,发现没找到合适内容 ...
- C-哈夫曼编码
/*author:windy_2*/ /*修正版*/ #include<stdio.h> #include<stdlib.h> #include<string.h> ...
- GCC 编译多个文件
今天写数据结构的example,定义了3个文件:lish.h list.c main.c list.h是list.c的头文件,mian.c中对list.h进行了引用.代码如下: list.h 1 #i ...
- php 排序和置顶功能实现
(1)排序操作思路 一般来说都是按照发布时间排序.时间戳大的靠前,所以用倒序desc,而不是asc (2)置顶操作思路: 点击置顶时,修改数据库addtime字段值为当前时间即可.因为排序是按照时间戳 ...
- excel表数据生成定长txt数据
项目作业中需要造数据,从txt文件中获取定长数据,直接从txt中修改,会显得十分麻烦,于是便利用excel自带的vba写了一个小工具.效果如下: A1表示字段名,A2表示长度,A3是数据,也可以增加字 ...
- zstack源码编译安装(1.7.x版本)
图片没粘贴过来,请看本人gitbook吧https://www.gitbook.com/book/jingtyu/how-to-learn-zstack-code 运行环境 zstack的安装方式有很 ...