Oracle中的insert/insert all/insert first
Oracle中的insert/insert all/insert first
1、概念
Oracle 中insert all 是指把 同一批 資料插入到 不同的表 中。
假如,現在有個需求,把表 t 的中資料分別插入到 t1、t2,如果你不知道 insert all, 你可能會使用 insert 插入 2 次,例如:
INSERT INTO t1(object_id, object_name) SELECT * FROM t;
INSERT INTO t2(object_id, object_name) SELECT * FROM t;
COMMIT;
其實,以上這樣的寫法,不一定正確。在 兩次 insert 過程中, 有可能 t 表的資料發生了改變,從而導致 t1、t2 表得到的資料不一樣,正確的寫法是用 insert all
INSERT ALL
INTO t1(object_id, object_name)
INTO t2(object_id, object_name)
SELECT * FROM t;
COMMIT;
1.1 思維導圖
1.2 基礎資料
DROP TABLE stu; -- if exists
CREATE TABLE stu (
s_id NUMBER,
s_xm VARCHAR2(30)
);
INSERT INTO stu(s_id, s_xm) VALUES (1, '小遊子');
INSERT INTO stu(s_id, s_xm) VALUES (2, '小優子');
INSERT INTO stu(s_id, s_xm) VALUES (3, '小倩子');
COMMIT;
2、例項分析
2.1 無條件插入
CREATE TABLE stu1 AS SELECT * from stu WHERE 1 = 2;
CREATE TABLE stu2 AS SELECT * from stu WHERE 1 = 2;
INSERT ALL
INTO stu1(s_id, s_xm)
INTO stu2(s_id, s_xm)
SELECT * FROM stu;
COMMIT;
SELECT * FROM stu1;
SELECT * FROM stu2;
2.2 有條件插入
2.2.1 insert first
對於每一行資料,只插入到 第一個when 條件成立的表,不繼續檢查其他條件。
DROP TABLE stu1; -- if exists
DROP TABLE stu2; -- if exists
CREATE TABLE stu1 AS SELECT * FROM stu WHERE 1 = 2;
CREATE TABLE stu2 AS SELECT * FROM stu WHERE 1 = 2;
INSERT FIRST
WHEN s_id <= 2 THEN
INTO stu1 (s_id, s_xm)
WHEN s_id >= 2 THEN -- 注意 2 是重複的哦
INTO stu2 (s_id, s_xm)
SELECT * FROM stu;
SELECT * FROM stu1;
SELECT * FROM stu2;
測試結果:
2.2.2 insert all
對於每一行資料,對 每一個when 條件都進行檢查,如果滿足條件就執行插入操作。
-- 僅將上述 FIRST 改為 ALL
DROP TABLE stu1; -- if exists
DROP TABLE stu2; -- if exists
CREATE TABLE stu1 AS SELECT * FROM stu WHERE 1 = 2;
CREATE TABLE stu2 AS SELECT * FROM stu WHERE 1 = 2;
INSERT ALL
WHEN s_id <= 2 THEN
INTO stu1 (s_id, s_xm)
WHEN s_id >= 2 THEN -- 注意 2 是重複的哦
INTO stu2 (s_id, s_xm)
SELECT * FROM stu;
SELECT * FROM stu1;
SELECT * FROM stu2;
測試結果:
3、其他操作
3.1 行轉列插入
DROP TABLE stu1; -- if exists
DROP TABLE stu2; -- if exists
CREATE TABLE stu1 (
s_id NUMBER,
s_xm VARCHAR(30) -- 資料型別要一致哦
);
CREATE TABLE stu2 (
s_id NUMBER,
s_xm1 VARCHAR2(30),
s_xm2 VARCHAR2(30),
s_xm3 VARCHAR2(30)
);
INSERT INTO stu2(s_id, s_xm1, s_xm2, s_xm3) VALUES (1, 'a1', 'b1', 'c1');
INSERT INTO stu2(s_id, s_xm1, s_xm2, s_xm3) VALUES (2, 'a2', 'b2', 'c2');
INSERT INTO stu2(s_id, s_xm1, s_xm2, s_xm3) VALUES (3, 'a3', 'b3', 'c3');
INSERT ALL
INTO stu1 VALUES (s_id, s_xm1)
INTO stu1 VALUES (s_id, s_xm2)
INTO stu1 VALUES (s_id, s_xm3)
SELECT * FROM stu2;
SELECT * FROM stu1;
測試結果:
————————————————
insert all官方文件解釋:
/*
多表插入語句的限制條件:
1. 只能對錶執行多表插入語句,不能對檢視或物化檢視執行;
2. 不能對遠端表執行多表插入語句;
3. 不能使用表集合表示式;
4. 不能超過999個目標列;
5. 在RAC環境中或目標表是索引組織表或目標表上建有BITMAP索引時,多表插入語句不能並行執行;
6. 多表插入語句不支援執行計劃穩定性;
7. 多表插入語句中的子查詢不能使用序列。
*/
第一步:準備資料
CREATE TABLE t1(product_id NUMBER, product_name VARCHAR2(80),MONTH NUMBER);
INSERT INTO t1 VALUES(111, '蘋果',1);
INSERT INTO t1 VALUES(222, '橘子',1);
INSERT INTO t1 VALUES(333, '香蕉',1);
第二部:insert all
INSERT ALL
INTO t2
VALUES (product_id, product_name,MONTH)
INTO t2
VALUES (product_id, product_name,MONTH+1)
INTO t2
VALUES (product_id, product_name,MONTH+2)
INTO t2
VALUES (product_id, product_name,MONTH+3)
SELECT product_id, product_name, MONTH
FROM t1;
這裡的表t2的資料下面會用到
---------------------------------------------------------------------------
第三步:有條件的insert all
insert all
when month=1 then
into t3
when month=2 then
into t4
else
into t5
select product_id,product_name,month from t2;
commit;
-------------------------------------------------------------------------
第四部:insert first (需要講解下)
insert first
when month=1 then
into t3 VALUES(product_id,product_name,month)
when product_id=111 then
into t4 VALUES(product_id,product_name,month)
else
into t5 VALUES(product_id,product_name,month)
select product_id,product_name,month from t2;
commit;
--------------------------------------------------------------------------
根據第二部,t2表的資料做測試。
查詢t4表發現:少了一條 111 蘋果 1
111 蘋果2
111 蘋果 3
111 蘋果 4
總結:insert first 當資料滿足第一when 條件的時候,不會作用在下面的when條件了,
簡而言之:當一條資料滿足條件後,即使滿足後面的條件也不會插入資料庫。
正常情況:如果資料滿足所有的when條件,每個表都會插入該條資料,insert first 資料只會插入一個表。
無條件的插入
Oracle中的insert all是指把同一批資料插入到不同的表中,假如如今有個需求:把t表中的資料分別插入t1,t2,假設你不知道insert all,你可能會使用insert插入2次,例如以下所看到的:
insert into t1(object_name,object_id) select * from t; insert into t2(object_name,object_id) select * from t; commit;
其實,以上這樣的寫法是錯誤的,由於在兩次insert的過程中,t表的資料有可能已經發生了變化,也就是說,t1,t2表得到的資料有可能不一樣,正確的寫法應該是採用insert all:
insert all into t1(object_name,object_id) into t2(object_name,object_id) select * from t; commit;
有條件的插入
兩者差別:
insert first:對於每一行資料,僅僅插入到第一個when條件成立的表,不繼續檢查其它條件。
insert all : 對於每一行資料,對每個when條件都進行檢查,假設滿足條件就執行插入操作。
看以下的樣例:
--insert first --前面等於1的條件被<=5含在內,FIRST就表示前面插入了,後面不會再插入了。 insert first when object_id = 1 then into t1(object_name,object_id) when object_id <=5 then into t2(object_name,object_id) select * from t; commit; select * from t1; OBJECT_NAME OBJECT_ID --------------------------------- --- ICOL$ 1 select * from t2; OBJECT_NAME OBJECT_ID --------------------------------- --- I_USER1 2 CON$ 3 UNDO$ 4 C_COBJ# 5 --insert all insert all when object_id = 1 then into t1(object_name,object_id) when object_id <=5 then into t2(object_name,object_id) select * from t; commit; SQL> select * from t1; OBJECT_NAME OBJECT_ID --------------------------------- --- ICOL$ 1 SQL> select * from t2; OBJECT_NAME OBJECT_ID --------------------------------- --- ICOL$ 1 I_USER1 2 CON$ 3 UNDO$ 4 C_COBJ# 5
行轉列插入
select * from sales_source_data; EMPLOYEE_ID WEEK_ID SALES_MON SALES_TUE SALES_WED SALES_THUR SALES_FRI ----------- ---------- ---------- ---------- ---------- ---------- ---------- 176 6 2000 3000 4000 5000 6000 insert all into sales_info values(employee_id,week_id,sales_mon) into sales_info values(employee_id,week_id,sales_tue) into sales_info values(employee_id,week_id,sales_wed) into sales_info values(employee_id,week_id,sales_thur) into sales_info values(employee_id,week_id,sales_fri) select employee_id,week_id,sales_mon,sales_tue, sales_wed,sales_thur,sales_fri from sales_source_data; select * from sales_info; EMPLOYEE_ID WEEK SALES ----------- ---------- ---------- 176 6 2000 176 6 3000 176 6 4000 176 6 5000 176 6 6000
多表插入語句的限制條件
1. 僅僅能對錶執行多表插入語句,不能對檢視或物化檢視執行;2. 不能對遠端表執行多表插入語句;
3. 不能使用表集合表示式;
4. 不能超過999個目標列;
5. 在RAC環境中或目標表是索引組織表或目標表上建有BITMAP索引時,多表插入語句不能並行執行;
6. 多表插入語句不支援執行計劃穩定性;
7. 多表插入語句中的子查詢不能使用序列。
About Me
........................................................................................................................ ● 本文作者:小麥苗,部分內容整理自網路,若有侵權請聯絡小麥苗刪除 ● 本文在itpub、部落格園、CSDN和個人微 信公眾號( xiaomaimiaolhr)上有同步更新 ● 本文itpub地址: http://blog.itpub.net/26736162 ● 本文部落格園地址: http://www.cnblogs.com/lhrbest ● 本文CSDN地址: https://blog.csdn.net/lihuarongaini ● 本文pdf版、個人簡介及小麥苗雲盤地址: http://blog.itpub.net/26736162/viewspace-1624453/ ● 資料庫筆試面試題庫及解答: http://blog.itpub.net/26736162/viewspace-2134706/ ● DBA寶典今日頭條號地址: http://www.toutiao.com/c/user/6401772890/#mid=1564638659405826 ........................................................................................................................ ● QQ群號: 230161599 、618766405 ● 微 信群:可加我微 信,我拉大家進群,非誠勿擾 ● 聯絡我請加QQ好友 ( 646634621 ),註明新增緣由 ● 於 2019-09-01 06:00 ~ 2019-09-31 24:00 在西安完成 ● 最新修改時間:2019-09-01 06:00 ~ 2019-09-31 24:00 ● 文章內容來源於小麥苗的學習筆記,部分整理自網路,若有侵權或不當之處還請諒解 ● 版權所有,歡迎分享本文,轉載請保留出處 ........................................................................................................................ ● 小麥苗的微店: https://weidian.com/s/793741433?wfr=c&ifr=shopdetail ● 小麥苗出版的資料庫類叢書: http://blog.itpub.net/26736162/viewspace-2142121/ ● 小麥苗OCP、OCM、高可用網路班: http://blog.itpub.net/26736162/viewspace-2148098/ ● 小麥苗騰訊課堂主頁: https://lhr.ke.qq.com/ ........................................................................................................................ 使用 微 信客戶端掃描下面的二維碼來關注小麥苗的微 信公眾號( xiaomaimiaolhr)及QQ群(DBA寶典)、新增小麥苗微 信, 學習最實用的資料庫技術。
........................................................................................................................ |
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26736162/viewspace-2655888/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- insert all和insert first語句的用法
- Oracle批量插入資料insert all into用法Oracle
- Oracle insert all一次插入多個表中Oracle
- lightdb -- merge into insert 相容 OracleOracle
- Oracle-insert into加日期Oracle
- insert into select
- Oracle中 Update和insert結合語法Oracle
- SQL__INSERTSQL
- E - Insert or Erase
- insert images to a plot
- 解析MySQL中INSERT INTO SELECT的使用MySql
- mysql insert的特殊用法MySql
- leetcode–57–Insert IntervalLeetCode
- SQLite Insert 語句SQLite
- ArrayList宣告,Add(), Insert();
- Oracle insert大量資料經驗之談Oracle
- oracle-資料庫- insert 插入語句Oracle資料庫
- mysql中last_insert_id()用法MySqlAST
- 怎樣提高insert的效能
- LeetCode之Insert Interval(Kotlin)LeetCodeKotlin
- Leetcode 35 Search Insert PositionLeetCode
- SQLite 之 INSERT OR REPLACE使用SQLite
- [20180907]insert+with+select.txt
- insert和insertSelective區別
- 1089 Insert or Merge (25分)
- mysql insert導致死鎖MySql
- insert()與substr()函式函式
- MySQL中REPLACE INTO和INSERT INTO的區別分析MySql
- 鍵盤insert操作怎麼取消?電腦鍵盤insert操作取消教程
- Python中insert用法及實戰案例!Python
- [20181120]奇怪的insert語句.txt
- mysql insert into ... select的鎖問題MySql
- DYLD_INSERT_LIBRARIES的那些事
- 故障分析 | 從 Insert 併發死鎖分析 Insert 加鎖原始碼邏輯原始碼
- 【MySQL】四、Insert buffer 漫談MySql
- SQLServer IDENTITY_INSERT問題SQLServerIDE
- [20180801]insert導致死鎖.txt
- 【SQL】9 SQL INSERT INTO 語句SQL