怎样对更新覆盖数据的功能进行优化,减少执行时间???

吃瓜日常 2019-04-10 09:56:59
最近公司要把B数据B表的数据从A数据库A表实时更新覆盖,我写了一个存储过程可以实现这个功能但是组长说要循环比对所有的数据,A,B两表也都要查询,能不能直接select直接查询两个表不同的地方,直接进行修改这样子,减少执行时间,提高效率,希望各位大佬能够给出意见,谢谢大家,下面是我的源代码,和模拟的A表B表
ALTER PROCEDURE [dbo].[QuaintTest] 
@rtn int output
AS
DECLARE @Piece_Id INT, @Piece_PId INT ,@Piece_Level INT,@Piece_Time DATETIME
BEGIN
SET NOCOUNT ON;
DECLARE
@cuisor_b_val CURSOR --创建游标变量
DECLARE cursor_B CURSOR --创建动态游标
FOR SELECT Piece_Id,Piece_PId,Piece_Level,Piece_Time
FROM APiece; --创建游标接受结果集
OPEN cursor_B --打开游标
fetch next from cursor_B INTO @Piece_Id,@Piece_PId,@Piece_Level,@Piece_Time --into的变量数量必须与游标查询结果集的列数相同

--0,Fetch语句成功。
--1:Fetch语句失败或行不在结果集中。
--2:提取的行不存在。
WHILE @@FETCH_STATUS=0 --判断FETCH语句是否执行成功
BEGIN
if exists(select * from APPiece where Piece_Id=@Piece_Id)
begin
UPDATE dbo.APPiece SET Piece_PId = @Piece_PId,Piece_Level=@Piece_Level,Piece_Time=@Piece_Time where Piece_Id=@Piece_Id
set @rtn=1 --有身份证相同的数据,进行更新处理
end
else
begin
insert into dbo.APPiece(Piece_Id,Piece_PId,Piece_Level,Piece_Time) values(@Piece_Id,@Piece_PId,@Piece_Level,@Piece_Time)
set @rtn=2 --没有相同的数据,进行插入处理
end
fetch next from cursor_B INTO @Piece_Id,@Piece_PId,@Piece_Level,@Piece_Time --移动游标
END
CLOSE cursor_B --关闭游标
DEALLOCATE cursor_B; --释放游标
END


...全文
209 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
吃瓜日常 2019-04-16
  • 打赏
  • 举报
回复
大家幫幫忙唄,特別感謝啊,各位大佬
吃瓜日常 2019-04-16
  • 打赏
  • 举报
回复
我自己再頂一下,還是沒有解決啊
吃瓜日常 2019-04-16
  • 打赏
  • 举报
回复
循環,輸入法...
吃瓜日常 2019-04-16
  • 打赏
  • 举报
回复
引用 21 楼 闭包客 的回复:
你的组长所说的“循环比较”和“一个语句”是矛盾的,你的游标做法,就是“循环比较”,“一个语句”,就不是循环的。
他的意思就是不要循環,可能我沒表達清楚,他的意思就是直接查不同,然後進行插入或者更新操作,而現在的方法游標是進行玄幻比較的,他覺得循環比較可能會影響效率,時間過長,是這個意思
闭包客 2019-04-16
  • 打赏
  • 举报
回复
你的组长所说的“循环比较”和“一个语句”是矛盾的,你的游标做法,就是“循环比较”,“一个语句”,就不是循环的。
闭包客 2019-04-16
  • 打赏
  • 举报
回复
可以的。 大概有两个语句:一个是 update …… from …… where ……;一个是 insert …… select …… from …… where …… 这种做法很常见的。
wanghui0380 2019-04-16
  • 打赏
  • 举报
回复
直接下触发器把 如果是整体比较,你首先得做个虚拟的key或者索引。判定抽象是 func<T1,T2,bool> 对吧,所以怎么判定依赖于你要判定那些东西 当然在执行上 可以 分开处理“增,删,改”,前两个你2条语句就可以。 而改的可以先left join 把A,B表联起来,然后在执行判定,update xxxx=B.xxxx where A.xxxx<>B.xxxx
大鱼> 2019-04-16
  • 打赏
  • 举报
回复
游标都使用上了,怎么能提高效率呢? 考虑换一种设计方式吧
吃瓜日常 2019-04-10
  • 打赏
  • 举报
回复
我可能没有表达清楚,组长是觉得我的要每条数据都进行循环比对,而这样的话太耗费时间,他就希望我能不能直接查询两个表不同的地方,然后进行插入操作,就是我是更新表的过程中进行比对,而组长的意思是直接查询不同的地方然后进行覆盖更新
吃瓜日常 2019-04-10
  • 打赏
  • 举报
回复
引用 2 楼 以专业开发人员为伍 的回复:
考虑到这类工作安排,你再来考虑要不要索引(是先导入然后创建索引还是先约束索引然后逐行插入)、要不要逐行“比对”(是一次导入几万条记录而不判断,还是一行一行进行判断处理)。

如果以遇到一个无脑的领导说要在营业时间搞什么批量导入,那么还是准备关门停业吧。
额,是基本上每天都要更新一下数据的,不过只更新一个表,表的数据量也没有太大,只是组长觉得我这样写不好,希望能优化一下
  • 打赏
  • 举报
回复
“技术”其实不算什么。领导可以轻松地安排你“今天晚上7点到明天早上3点加班,然后自己打车回家,然后早上可以最迟到11点再来上班”。领导可以把技术人员看得很低很低,反而是技术人员反而整天研究什么“增删改查”而就不知道该从业务和管理入手来设计软件按。
  • 打赏
  • 举报
回复
考虑到这类工作安排,你再来考虑要不要索引(是先导入然后创建索引还是先约束索引然后逐行插入)、要不要逐行“比对”(是一次导入几万条记录而不判断,还是一行一行进行判断处理)。 如果以遇到一个无脑的领导说要在营业时间搞什么批量导入,那么还是准备关门停业吧。
  • 打赏
  • 举报
回复
如果一年才做一次,那么选择凌晨12点开始做,确保3个小时内能做完,万一出现意外则重新做。能这样安排,这个时候你再来考虑这类需求。
吃瓜日常 2019-04-10
  • 打赏
  • 举报
回复
引用 14 楼 坏蛋栀子花 的回复:
小例子 可以参考下
假设 A表与B表ID一致

IF object_id('tempdb..#temp_A') is not null
drop table #temp_A
go

select * into #temp_A from (
select '1' as ID,'10' as Name
union
select '2' as ID,'20' as Name
union
select '3' as ID,'30' as Name
union
select '4' as ID,'30' as Name
) as T

IF object_id('tempdb..#temp_B') is not null
drop table #temp_B
go

select * into #temp_B from (
select '1' as ID,'5' as Name
union
select '2' as ID,'20' as Name
union
select '3' as ID,'6' as Name

) as T


--查询的数据

select a.ID,a.Name from #temp_A as a
inner join #temp_B as b on a.ID=b.ID
where a.name!=b.name


--批量修改 修改2条数据
update b set b.name=a.name from #temp_A as a
inner join #temp_B as b on a.ID=b.ID
where a.name!=b.name


--新增的数据 新增一条 具体新增语句 就不写了
select a.ID,a.Name from #temp_A as a
left join #temp_B as b on a.ID=b.ID
where b.id is null

咳咳,不好意思啊,我是实习生菜鸟,首先非常感谢你们为我解答,下面的查询修改新增语句能看懂,但是上面的IF语句不是很能看懂,,那如果是以上面贴的两张图里的表为例呢?
笨蛋girl 2019-04-10
  • 打赏
  • 举报
回复
小例子 可以参考下
假设 A表与B表ID一致

IF object_id('tempdb..#temp_A') is not null
drop table #temp_A
go

select * into #temp_A from (
select '1' as ID,'10' as Name
union
select '2' as ID,'20' as Name
union
select '3' as ID,'30' as Name
union
select '4' as ID,'30' as Name
) as T

IF object_id('tempdb..#temp_B') is not null
drop table #temp_B
go

select * into #temp_B from (
select '1' as ID,'5' as Name
union
select '2' as ID,'20' as Name
union
select '3' as ID,'6' as Name

) as T


--查询的数据

select a.ID,a.Name from #temp_A as a
inner join #temp_B as b on a.ID=b.ID
where a.name!=b.name


--批量修改 修改2条数据
update b set b.name=a.name from #temp_A as a
inner join #temp_B as b on a.ID=b.ID
where a.name!=b.name


--新增的数据 新增一条 具体新增语句 就不写了
select a.ID,a.Name from #temp_A as a
left join #temp_B as b on a.ID=b.ID
where b.id is null
正怒月神 2019-04-10
  • 打赏
  • 举报
回复
引用 9 楼 吃瓜日常 的回复:
[quote=引用 8 楼 正怒月神 的回复:] 那你直接做数据同步不就好了?发布订阅服务
订阅服务?实际需求两个表并不是完全相同的,有一部分字段里面的数据是不需要跟随更新和被覆盖的,可以用订阅服务吗[/quote] 如果并不完全相同的话,那么就不合适了。
笨蛋girl 2019-04-10
  • 打赏
  • 举报
回复
你写语句的时候控制下呗 比如 有 a.b.c 三个字段 你只查询你需要的 a,c 就可以 不需要的不用显示出来。最后确定查询的语句 使用批量修改就可以了
吃瓜日常 2019-04-10
  • 打赏
  • 举报
回复
引用 10 楼 坏蛋栀子花 的回复:
你可以写SQL查询异同之处 进行修改或者新增。(不了解你表结构,只能你自己写了) 或者 如果以A库A表为主,数据同步就OK了

组长意思就是你这种先写SQL查询不同的数据,然后进行修改或者插入,确实是以A库A表为主的,但是两个表的字段并不完全相同,B表中有几个字段是不需要参与更新数据同步操作的
笨蛋girl 2019-04-10
  • 打赏
  • 举报
回复
你可以写SQL查询异同之处 进行修改或者新增。(不了解你表结构,只能你自己写了) 或者 如果以A库A表为主,数据同步就OK了
吃瓜日常 2019-04-10
  • 打赏
  • 举报
回复
引用 8 楼 正怒月神 的回复:
那你直接做数据同步不就好了?发布订阅服务

订阅服务?实际需求两个表并不是完全相同的,有一部分字段里面的数据是不需要跟随更新和被覆盖的,可以用订阅服务吗
加载更多回复(3)

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

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