問題
公司的項(xiàng)目愿待,有個(gè)功能每次使用需要向數(shù)據(jù)庫插入很多數(shù)據(jù)顶滩,導(dǎo)致頁面等待很長時(shí)間才有結(jié)果铃诬。
數(shù)據(jù)庫:oracle11g
id:采用sequence自增
每次循環(huán)贿肩,都會(huì)查詢一次sequence烦味,然后insert一條數(shù)據(jù)聂使,性能非常低。
改進(jìn)
改成一次插入多條數(shù)據(jù)谬俄,id通過觸發(fā)器自動(dòng)設(shè)置柏靶,不再每次先查詢sequence,效率提高非常多溃论。
oracle一次插入多條的方法
在oracle里面屎蜓,不支持像mysql那樣直接在后面拼多個(gè)記錄。oracle中有兩種方法達(dá)到批量插入的效果:
方法一:采用union all拼接查詢方式
本文不做詳細(xì)介紹钥勋,可在網(wǎng)上查看相關(guān)資料炬转。
insert into pager (PAG_ID,PAG_PARENT,PAG_NAME,PAG_ACTIVE)
select 8000,0,'Multi 8000',1 from dual
union all select 8001,0,'Multi 8001',1 from dual
方法二:采用insert all的方式
由于insert all方式插入多條時(shí),通過sequence獲取的值是同一個(gè)算灸,不會(huì)自動(dòng)獲取多個(gè)扼劈,所以id需要通過其他方式設(shè)置,(我這里采用觸發(fā)器方式自動(dòng)設(shè)置id)
1菲驴、創(chuàng)建測(cè)試表:
create table test_insert(
data_id number(10) primary key,
user_name varchar2(30),
address varchar2(50)
)
data_id為主鍵荐吵,通過sequence產(chǎn)生主鍵值。
2谢翎、創(chuàng)建序列:
create sequence seq_test_insert
minvalue 1
maxvalue 999999999999999999999999
start with 1
increment by 1
cache 20;
3捍靠、創(chuàng)建觸發(fā)器
通過觸發(fā)器自動(dòng)給insert語句設(shè)置id值
create or replace trigger tr_test_insert
before insert on test_insert
for each row
begin
select seq_test_insert.nextval into :new.data_id from dual;
end;
4、插入測(cè)試數(shù)據(jù):
insert all
into test_insert(user_name,address) values('aaa','henan')
into test_insert(user_name,address) values('bbb','shanghai')
into test_insert(user_name,address) values('ccc','beijing')
select * from dual;
相當(dāng)于下面三個(gè)insert into語句森逮,但性能比單條高多了榨婆。
insert into test_insert(user_name,address) values('aaa','henan');
insert into test_insert(user_name,address) values('bbb','shanghai');
insert into test_insert(user_name,address) values('ccc','beijing');
需要注意的是,在insert all語句里不能直接使用seq_test_insert.nextval褒侧,因?yàn)榧幢忝總€(gè)into語句里都加上seq_test_insert.nextval也不會(huì)獲得多個(gè)值良风。
5、查看測(cè)試數(shù)據(jù)
select * from test_insert;
結(jié)果如下圖:
另外闷供,insert all還支持往不同的表里插入數(shù)據(jù)烟央,如:
insert all
into table1(filed1,filed2)values('value1','value2')
into table2(字段1,字段2歪脏,字段3) values(值1疑俭,值2,值3)
select * from dual;