数据库“有则更新,无则插入”的另一种写法
对于这样一个表character,id为主键:
id name gender race
--------------------------------------------------------
1 JimRaynor male terran
2 SarahKerrigan femal zerg
3 Zeratul unknown protoss
--------------------------------------------------------
要实施一个“有则更新,无则插入”的操作可以这样做
declare count int;
Select count(*) into count from character where id = **;
if count > 0 then
Update character Set name=**,gender=**,race=** where id = **;
else
Insert Into character(id,name,gender,race) values (**,**,**,**);
end if;
这样的操作可以解决问题,但是经过研究有另一种写法,能够省略掉Select部分
1、对于单行数据可以这样写
Update character Set name=**,gender=**,race=** where id = **;
if SQL%ROWCOUNT = 0 then
Insert Into character(id,name,gender,race) values (**,**,**,**);
end if;
其中SQL%ROWCOUNT返回上一次写操作影响的行数,逻辑应该比较清楚,就不阐述了,这是ORACLE的写法,对于SQLSERVER的话可以用@@rowcount返回影响行数,其余部分大体类似,至于效率问题,我没有做过测试,所以不敢妄下结论这个更高效,因为count()函数是不会遍历数据表的,只是提供另一种写法而已
2、对于两表之间的同步操作
如果有两个表之间需要进行同步操作,可以使用游标,但先不妄下结论说游标效率低下,光游标的写法就比较繁琐,假设有两个结构一样的character表,分别名为character1和character2,要把character1导入到character2中,如下写,两句SQL就可以搞定。
Update character2 c2 Set
c2.name = (Select c1.name from character1 c1 where c1.id = c2.id),
c2.gender = (Select c1.gender from character1 c1 where c1.id = c2.id),
c2.race = (Select c1.race from character1 c1 where c1.id = c2.id);
Insert into character2 c2
Select c1.id,c1.name,c1.gender,c1.race from character1 c1 where c1.id not in (Select id from character2);
逻辑第一句是更新操作,这里用了几个子查询,把需要的值直接从源表中取出并更新到目标表中,第二句为插入,将源表中存在目标表中不存在的数据全部Select出来,一次性插入到目标表。如果两表之间的结构有差别可以使用视图来解决,这个就不再罗嗦了。
这些旨在抛砖引玉,SQL不像程序那样属于过程操作的语言,所以有些地方需要跳出写代码的循环、判断这些固定逻辑思维,有时候要写几十行代码的地方其实一个Select就可以搞定,多练习这方面视野会更加开阔。
(注:以上代码均为盲写且未经过速度测试,请斟酌使用)