数据库“有则更新,无则插入”的另一种写法

对于这样一个表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就可以搞定,多练习这方面视野会更加开阔。

 

(注:以上代码均为盲写且未经过速度测试,请斟酌使用)

posted @ 2012-10-24 08:03  大智若简  阅读(2674)  评论(0编辑  收藏  举报