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没有.还有一个最大的好处就 ...
随机推荐
- 设计模式:代理模式是什么,Spring AOP还和它有关系?
接着学习设计模式系列,今天讲解的是代理模式. 定义 什么是代理模式? 代理模式,也叫委托模式,其定义是给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用.它包含了三个角色: Subject: ...
- 关系型数据库MySql 数据类型与约束
MySql数据库 :数据类型与约束 注意 : 在创建数据表的时候,需要对数据表中的字段设置 数据类型和约束, 便于检测用户输入的数据是否正确有效. 1 数据类型 数据类型的选用原则 : 够用就行,尽 ...
- Java项目案例之---常用工具类练习
常用工具类练习 1. 请根据控制台输入的特定日期格式拆分日期,如:请输入一个日期(格式如:**月**日****年),经过处理得到:****年**月**日 import java.util.Scanne ...
- 一台服务器通过nginx配置多个域名(80端口)
1. 问题描述 多个域名对应一个服务器,为了避免域名后增加端口号,两个域名都需要占用80端口号,使用nginx来进行配置. 2. 解决方案 目前项目中,线上正在使用(100%可用)多域名对应一个服务器 ...
- 深入学习Spring框架(四)- 事务管理
1.什么是事务? 事务(Transaction)是一个操作序列.这些操作要么都做,要么都不做,是一个不可分割的工作单位,是数据库环境中的逻辑工作单位.事务是为了保证数据库的完整性.例如:A给B转账,需 ...
- linux应用程序设计--GDB调试
GDB简介:GDB是GNU发布的一款功能强大的程序调试工具,GDB主要完成下面三个方面功能: 一.GDB的使用操作 1.启动被调试程序. 2.让被调试的程序在指定的位置停住. 3.当程序被停住时,可以 ...
- 使用WebService发布soap接口,并实现客户端的https验证
什么是https HTTPS其实是有两部分组成:HTTP + SSL / TLS, 也就是在HTTP上又加了一层处理加密信息的模块,并且会进行身份的验证. 如何进行身份验证? 首先我们要明白什么是对称 ...
- Flutter学习笔记(8)--Dart面向对象
如需转载,请注明出处:Flutter学习笔记(7)--Dart异常处理 Dart作为高级语言,支持面向对象的很多特性,并且支持基于mixin的继承方式,基于mixin的继承方式是指:一个类可以继承自多 ...
- c++小游戏——杀手
杀手小游戏 会有一个存活者:(1 2 3 4 5),如果出现(1 0 3 4 5),代表二号已经死了. 一号有3次复活权 且有一次随机诅咒权(即当自己被杀死时,会随机诅咒另外一个人,当然不是死人或自己 ...
- WMI_COM_API
Win32_Processor // CPU 处理器 Win32_PhysicalMemory // 物理内存 Win32_Keyboard // 键盘 Win32_PointingDevice // ...