关于表数据更新的问题
有一个总表tb1(mobile,col1,col2,col3,col4,col5,col6,col7,col8,col9,col10,inputtime,source),以mobile为主键,可以将col1,col2等列视为mobile的属性,inputtime获取数据更新时的系统时间记录为数据更新时间,source为数据来源,来源可能有多种,不同来源以“,”逗号间隔。
现有一个实际应用是时常有txt格式的新数据过来,在这些新数据中必有mobile与source字段,但是可能只会有(mobile,col1, source);下次的新数据可能只有(mobile,col2,source),新数据中的mobile有些会与tb1中的mobile重复。
现需要将每次过来的新数据导入到tb1中,类似merge into的功能,mobile相同的,update;mobile不同的,insert。同时更新inputtime,source以“,”逗号为间隔继续添加,如“问卷调查,会员信息”,如果有新的来源继续添加。
如果每一次更新都建立一个新表存储新数据,然后执行语句的话,十分繁琐,且容易出错,想问一下大神们有没有什么简洁的办法。我目前想到的是建立一个新表tb2(mobile,col1,col2,col3,col4,col5,col6,col7,col8,col9,col10,source),每次将新数据导入到该表中,然后用触发器触发更新tb1。
想知道:1.如果用我想到的方法的话,触发器该怎么写(汗~oracle只对查询熟悉一些,其他地方是小白
)
2.如果不用触发器,还有没有更好的办法,有次听到一个前辈说用存储过程也可以,但是存储过程也不知道怎么写~
求教诸位大神 了!
------解决思路----------------------
引用:
你自己先把数据导入TB2,然后用一下的存储过程来实现(自己再稍微改动一下)
create or replace procedure test1 is
l_count number := 0;
begin
for c1 in (select mobile, col1,...sysdate inputtime, source from tb2) loop
select count(*) into l_count from tgp_funds where fnd_id = c1.fnd_id;
if l_count > 0 then
update tgp_funds tb1
set tb1.col1 = nvl(c1.col1, tb1.col1),
tb1.col2 = nvl(c1.col2, tb1.col2),
.. . inputtime = sysdate,
source = source
------解决思路----------------------
','
------解决思路----------------------
c1.source
where tb1.fnd_id = c1.fnd_id;
else
insert into tgp_funds values c1;
end if;
end loop;
commit;
exception
when others then
dbms_output.put_line('Error happened!!');
end test1;
------解决思路----------------------
有点改动:
create or replace procedure test1 is
l_count number := 0;
begin
for c1 in (select mobile, col1,...sysdate inputtime, source from tb2) loop
select count(*) into l_count from tb1 where mobile = c1.mobile;
if l_count > 0 then
update tb1
set tb1.col1 = nvl(c1.col1, tb1.col1),
tb1.col2 = nvl(c1.col2, tb1.col2),
.. . inputtime = sysdate,
source = source
------解决思路----------------------
','
------解决思路----------------------
c1.source
where tb1.mobile = c1.mobile;
else
insert into tb1 values c1;
end if;
end loop;
commit;
exception
when others then
dbms_output.put_line('Error happened!!');
end test1;
------解决思路----------------------
引用:有点改动:
create or replace procedure test1 is
l_count number := 0;
begin
for c1 in (select mobile, col1,...sysdate inputtime, source from tb2) loop
select count(*) into l_count from tb1 where mobile = c1.mobile;
if l_count > 0 then
update tb1
set tb1.col1 = nvl(c1.col1, tb1.col1),
tb1.col2 = nvl(c1.col2, tb1.col2),
.. . inputtime = sysdate,
source = source
------解决思路----------------------
','
------解决思路----------------------
c1.source
where tb1.mobile = c1.mobile;
else
insert into tb1 values c1;
end if;
end loop;
commit;
exception
when others then
dbms_output.put_line('Error happened!!');
end test1;
为什么不用merge呢?
create or replace procedure test1 is
l_count number := 0;
begin
merge into tb1
using tb2
on tb1.mobile = tb2.mobile
when matched then
update set
tb1.col1 = nvl(tb2.col1, tb1.col1),
tb1.col2 = nvl(tb2.col2, tb1.col2),
.. . inputtime = sysdate,
source = source
------解决思路----------------------
','
------解决思路----------------------
tb2.source
where tb1.mobile = tb2.mobile
;
when not matched then
insert (
mobile,
col1,
col2,
.
.
.
inputtime,
source
)
values(
mobile,
col1,
col2,
.
.
.
sysdate,
source
)
;
commit;
end;
------解决思路----------------------
如果我做的话,也是建一个和tb1结构一样的tb2,然后每次都把txt的数据sqlldr进去,补齐缺失字段。存储过程再用merge ,版主的那种写法作为一个懒人第一眼没看懂就没再 看了