更新子集时实行先删除后插入,感觉很粗暴,有更好的方法吗

yyixin 2018-01-25 10:28:38
如:

if object_id('tempdb.dbo.#UserRoles') is not null drop table #UserRoles

create table #UserRoles(UserId int ,RoleName varchar(50))
insert into #UserRoles select 1, 'a'
insert into #UserRoles select 1 ,'b'
insert into #UserRoles select 1 ,'c'
insert into #UserRoles select 1, 'd'
insert into #UserRoles select 2, 'e'
insert into #UserRoles select 2 ,'f'
insert into #UserRoles select 2 ,'g'

select * from #UserRoles

-- 删除旧的角色
DELETE FROM #UserRoles WHERE UserId = 1

-- 插入新的角色
insert into #UserRoles select 1, 'c'
insert into #UserRoles select 1 ,'b'
insert into #UserRoles select 1 ,'f'


select * from #UserRoles

...全文
766 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
yyixin 2018-01-26
  • 打赏
  • 举报
回复
谢谢。是2#楼MERGE这个方法,查了一下好像只需遍历一次,应该高效一点。实际的场景并非只是用户角色这一块,且数据的点多,修改有些频。
吉普赛的歌 版主 2018-01-25
  • 打赏
  • 举报
回复
引用 9 楼 yyixin 的回复:
[quote=引用 8 楼 yenange 的回复:] 这个是处理用户角色之类的吧, 一般情况下很少操作的了。 这样设计其实问题不大, 没必要改。
谢谢。想先用二楼的方法。非专业人员,深一点的就不懂了。[/quote] 二楼的办法也不好, 因为加了逗号, 最终查询时还得自己分隔。 没必要折腾的了
yyixin 2018-01-25
  • 打赏
  • 举报
回复
引用 8 楼 yenange 的回复:
这个是处理用户角色之类的吧, 一般情况下很少操作的了。 这样设计其实问题不大, 没必要改。
谢谢。想先用二楼的方法。非专业人员,深一点的就不懂了。
吉普赛的歌 版主 2018-01-25
  • 打赏
  • 举报
回复
这个是处理用户角色之类的吧, 一般情况下很少操作的了。 这样设计其实问题不大, 没必要改。
yyixin 2018-01-25
  • 打赏
  • 举报
回复
引用 5 楼 zjcxc 的回复:
正常的更新,是把满足条件的明确更新成某个值,有明确的多(或一)对一的关系,这是 UPDATE 支持的 楼主的示例是粗暴的把满足条件的数据,用另一组数据来替换,是多(或一)对多(或一)关系,这是 UPDATE 不支持的 所以如果要用 UPDATE, 需要找一明确的多对一关系
谢谢!我想该考虑在业务的处理上作一些改变了。谢谢大家。
zjcxc 元老 2018-01-25
  • 打赏
  • 举报
回复
正常的更新,是把满足条件的明确更新成某个值,有明确的多(或一)对一的关系,这是 UPDATE 支持的 楼主的示例是粗暴的把满足条件的数据,用另一组数据来替换,是多(或一)对多(或一)关系,这是 UPDATE 不支持的 所以如果要用 UPDATE, 需要找一明确的多对一关系
听雨停了 2018-01-25
  • 打赏
  • 举报
回复

WITH cte as (
	SELECT * ,row_number() over(ORDER BY #UserRoles.RoleName) AS rn 
	FROM #UserRoles
	WHERE UserId=1	
) 
UPDATE cte SET RoleName =( CASE rn WHEN 1 THEN 'c' WHEN 2 THEN  'b' WHEN 3 THEN 'f' END) 
yyixin 2018-01-25
  • 打赏
  • 举报
回复
考虑到还要记录一些其他的信息,如创建时间。还有查询效率的问题,不适合改变结构
中国风 2018-01-25
  • 打赏
  • 举报
回复
传参改为XML或表类型或字符串
改用MERGE
e.g.
;WITH S(UserId,RoleName)
AS
(
select 1, 'c'
UNION ALL select 1 ,'b'
UNION ALL select 1 ,'f'
),T AS
(SELECT * FROM #UserRoles WHERE UserId = 1)
MERGE T
USING S ON (T.UserId=S.UserID AND T.RoleName=S.RoleName)
WHEN NOT MATCHED THEN
INSERT(UserId,RoleName)VALUES(S.UserId,S.RoleName)
WHEN NOT MATCHED BY SOURCE THEN
DELETE;
zjcxc 元老 2018-01-25
  • 打赏
  • 举报
回复
既然你觉得粗暴,那你直接更新不就行了 从你的示例来看,是你的需求比较粗暴
二月十六 版主 2018-01-25
  • 打赏
  • 举报
回复
改一下数据结构 UserId Roles 1 ‘a,b,c' 每次update更新
# GNS3概述       GNS3 是一款具有图形化界面、可以运行在多平台(包括Windows, Linux和Mac OS等)上的网络虚拟软件。该软件能够在计算机上虚拟出思科路由器和交换机的硬件,且加载思科路由器和交换机的IOS(真实模拟),通过它可以体验 Cisco 网际操作系统 IOS或检验将要在真实的路山器上部署实施的相关配置。       Cisco 网络设备管理员或是想要通过 CCNA、CCNP、CCIE等Cisco认证考试的相关人士可以通过它来完成相关的实验;同让我们体验和真实路由器和交换机完全一样的学习过程,在某些方面比真实设备的功能还要强大。       所以 GNS3 对于我们学习计算机网络原理的学生,也是必不可少的工具。# VMWare Workstation       桌面级虚拟化产品,大名鼎鼎,不言而喻。# Wireshark 抓包工具       本章还演示了在GNS3搭建的网络环境,使用Wireshark抓包工具捕获数据包,可以捕获网络拓扑中任意链路上通过的数据包,为学习后面的章节打下坚实的基础。# SecureCRT       连接、操作和管理 GNS3 的强大功能软件,之前Linux教学中已经详细介绍使用。# PacketTracer       思科路由器交换机模拟软件,Packet Tracer 是由Cisco公司发布的一个辅助学习工具,为学习CCNA课程的网络‘初学者’设计、配置、排除网络故障提供了网络模拟环境。学生可在软件的图形用户界面上直接使用拖曳方法建立网络拓扑,软件中实现的IOS子集允许学生配置设备;并可提供数据包在网络中行进的详细处理过程,观察网络实运行情况。 # 重点提示       本章不属于计算机网络原理的内容,但要想更好地理解后面讲到的计算机网络原理,更具体地探索计算机通信过程,还需要捕获数据包、分析数据包的数据链路层首部、网络层首部、传输层首部以及应用层协议,这就需要使用网络设备来搭建学习环境。

34,590

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧